ROWID
to pseudokolumna
, nie jest częścią widoku słownika danych tabeli (np. nie pojawia się w dba_tab_columns
), więc nie jest zawarte w %rowtype
. Rekord PL/SQL – z którego konstruujesz tablicę PL/SQL – nie ma fizycznej pamięci, więc nie ma rzeczywistego ani pseudo-rowidu.
Jeśli naprawdę chcesz przechowywać identyfikator wiersza w rekordzie/tabeli, musisz jawnie zadeklarować typ:
create or replace package dat_pkg is
type typ_dat_rec is record (
data_id data_test.data_id%type,
data_value data_test.data_value%type,
data_rowid rowid);
type typ_dat_tst is table of data_test%rowtype index by pls_integer;
procedure proc_test (p_dat typ_dat_tst);
end dat_pkg;
/
Nie możesz wywołać pola rekordu tylko rowid
ponieważ jest to typ danych, więc poprzedziłem go przedrostkiem data_
ale może wolisz coś innego. A potem musisz użyć tej nazwy pola w treści swojego pakietu, oczywiście:
create or replace package body dat_pkg is
procedure proc_test (p_dat typ_dat_tst)
is
begin
for i in 1..p_dat.count loop
update data_test
set data_value = p_dat(i).data_value
where data_id = p_dat(i).data_id
and rowid = p_dat(i).data_rowid;
end loop;
end proc_test;
end dat_pkg;
/
Możesz, zgodnie z sugestią, przechowywać cały typ wiersza i identyfikator wiersza jako dwa pola w typie rekordu:
create or replace package dat_pkg is
type typ_dat_rec is record (
data_rec data_test%rowtype,
data_rowid rowid);
type typ_dat_tst is table of typ_dat_rec index by pls_integer;
procedure proc_test (p_dat typ_dat_tst);
end dat_pkg;
/
ale to sprawia, że odwoływanie się do pól jest nieco bardziej niezręczne:
...
for i in 1..p_dat.count loop
update data_test
set data_value = p_dat(i).data_rec.data_value
where data_id = p_dat(i).data_rec.data_id
and rowid = p_dat(i).data_rowid;
end loop;
...
i prawdopodobnie sprawi to, że zapełnianie kolekcji będzie również trudniejsze. Ponieważ i tak musisz znać wszystkie nazwy kolumn/pól, aby móc odwoływać się do nich w pętli, nie jestem pewien, czy jest to duża zaleta, ale może się to okazać ładniejsze.
Oczywiście wykonanie tego w ogóle zakłada, że twoja kolekcja jest wypełniana z podzbioru danych z tabeli w tej samej bazie danych, a nawet sesji, ponieważ rowid
wiersza może się zmieniać w czasie. Możesz także zajrzeć do forall
składnia zastępująca for
pętla, w zależności od tego, co naprawdę robisz. (Ale powinieneś również zastanowić się, czy w ogóle potrzebujesz kolekcji - jeśli po prostu zapełnisz kolekcję, a następnie użyjesz jej do aktualizacji, pojedyncza aktualizacja SQL będzie jeszcze szybsza...)