ROWID
is een pseudokolom
, het maakt geen deel uit van de datadictionary-weergave van de tabel (het verschijnt bijvoorbeeld niet in dba_tab_columns
), dus het is niet opgenomen in de %rowtype
. Een PL/SQL-record - waar u een PL/SQL-tabel van maakt - heeft geen fysieke opslag, dus geen echte of pseudo-rowid.
Als u de rij-ID echt in een record/tabel wilt opslaan, moet u het type expliciet declareren:
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;
/
Je kunt het recordveld niet gewoon rowid
noemen aangezien dat een gegevenstype is, heb ik het voorafgegaan door data_
maar misschien heb je liever iets anders. En dan moet je die veldnaam natuurlijk in de body van je pakket gebruiken:
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;
/
Je zou, zoals je voorstelde, het hele rijtype en . kunnen opslaan de rij-ID als twee velden in het recordtype:
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;
/
maar dat maakt het verwijzen naar de velden wat lastiger:
...
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;
...
en het zal het vullen van de collectie waarschijnlijk ook lastiger maken. Omdat je toch alle kolom-/veldnamen moet kennen om er in de loop naar te kunnen verwijzen, weet ik niet zeker of er veel voordeel is, maar misschien vind je het netter.
Als u dit doet, gaat u er natuurlijk van uit dat uw verzameling wordt gevuld met een subset van gegevens uit de tabel in dezelfde DB en zelfs in dezelfde sessie, aangezien de rowid
van een rij kan in de loop van de tijd veranderen. Misschien wil je ook kijken naar de forall
syntaxis om uw for
. te vervangen lus, afhankelijk van wat je echt aan het doen bent. (Maar je moet ook overwegen of je de collectie wel nodig hebt - als je alleen de collectie vult en die vervolgens voor de update gebruikt, dan zou een enkele SQL-update nog sneller zijn...)