ROWID
е псевдоколона
, то не е част от изгледа на речника на данните на таблицата (напр. не се показва в dba_tab_columns
), така че не е включен в %rowtype
. PL/SQL запис – от който създавате PL/SQL таблица – няма физическо хранилище, така че няма реален или псевдоред.
Ако наистина искате да съхраните идентификатора на реда в запис/таблица, ще трябва изрично да декларирате типа:
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;
/
Не можете да наричате полето за запис просто rowid
тъй като това е тип данни, затова го поставих с префикс data_
но може да предпочетете нещо друго. След това трябва да използвате това име на полето в тялото на вашия пакет, очевидно:
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;
/
Можете, както предложихте, да съхраните целия тип ред и ID на реда като две полета в типа запис:
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;
/
но това прави позоваването на полетата малко по-неудобно:
...
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;
...
и това вероятно ще направи попълването на колекцията също по-неудобно. Тъй като така или иначе трябва да знаете всички имена на колони/полета, за да можете да се позовавате на тях в цикъла, не съм сигурен, че има голямо предимство, но може да ви се стори по-изпипано.
Разбира се, извършването на това изобщо предполага, че вашата колекция се попълва от подмножество от данни от таблицата в същата DB и дори сесия, тъй като rowid
на ред може да се промени с времето. Може също да искате да разгледате forall
синтаксис, за да замените вашия for
цикъл, в зависимост от това какво наистина правите. (Но трябва също така да помислите дали имате нужда от колекцията изобщо - ако просто попълвате колекцията и след това използвате това за актуализацията, тогава една актуализация на SQL ще бъде още по-бърза...)