ROWID
er en pseudokolonne
, det er ikke en del af tabellens dataordbogsvisning (det vises f.eks. ikke i dba_tab_columns
), så det er ikke inkluderet i %rowtype
. En PL/SQL-record - hvilket er det, du konstruerer en PL/SQL-tabel af - har ingen fysisk lagring, så ingen reel eller pseudo rowid.
Hvis du virkelig vil gemme række-id'et i en post/tabel, skal du udtrykkeligt angive typen:
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;
/
Du kan ikke kalde registreringsfeltet bare rowid
da det er en datatype, så jeg har foranstillet den med data_
men du foretrækker måske noget andet. Og så skal du bruge det feltnavn i din pakketekst, selvfølgelig:
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;
/
Du kunne, som du foreslog, gemme hele rækketypen og række-id'et som to felter i posttypen:
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;
/
men det gør det lidt mere akavet at henvise til felterne:
...
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;
...
og det vil sandsynligvis også gøre det mere akavet at befolke samlingen. Da du alligevel skal kende alle kolonne-/feltnavne for at kunne henvise til dem i løkken, er jeg ikke sikker på, at der er den store fordel, men du kan finde det pænere.
At gøre dette overhovedet forudsætter naturligvis, at din samling udfyldes fra et undersæt af data fra tabellen i samme DB og lige session, da en rækkes rowid
kan ændre sig over tid. Du vil måske også se på forall
syntaks til at erstatte din for
loop, afhængigt af hvad du virkelig laver. (Men du bør også overveje, om du overhovedet har brug for samlingen - hvis du bare udfylder samlingen og derefter bruger den til opdateringen, så ville en enkelt SQL-opdatering stadig være hurtigere...)