ROWID
é uma pseudocoluna
, não faz parte da visualização do dicionário de dados da tabela (por exemplo, não aparece em dba_tab_columns
), portanto, não está incluído no %rowtype
. Um registro PL/SQL - que é o que você está construindo em uma tabela PL/SQL - não tem armazenamento físico, portanto, nenhum rowid real ou pseudo. Se você realmente deseja armazenar o ID da linha em um registro/tabela, você teria que declarar o tipo explicitamente:
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;
/
Você não pode chamar o campo de registro apenas
rowid
como esse é um tipo de dados, eu o prefixei com data_
mas você pode preferir outra coisa. E então você precisa usar esse nome de campo no corpo do seu pacote, obviamente: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;
/
Você pode, como sugeriu, armazenar todo o tipo de linha e o ID da linha como dois campos no tipo de registro:
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;
/
mas isso torna a referência aos campos um pouco mais complicada:
...
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;
...
e provavelmente tornará o preenchimento da coleção mais complicado também. Como você precisa conhecer todos os nomes de colunas/campos de qualquer maneira para poder se referir a eles no loop, não tenho certeza se há muita vantagem, mas você pode achar mais limpo.
Obviamente, fazer isso pressupõe que sua coleção esteja sendo preenchida a partir de um subconjunto de dados da tabela no mesmo banco de dados e até mesmo na sessão, pois o
rowid
de uma linha pode mudar ao longo do tempo. Você também pode querer olhar para o forall
sintaxe para substituir seu for
loop, dependendo do que você está realmente fazendo. (Mas você também deve considerar se precisa da coleção - se você estiver apenas preenchendo a coleção e usando isso para a atualização, uma única atualização do SQL seria ainda mais rápida ...)