关于我以前的问题,Include RowId value in Nested Table,
我有以下示例表:
create table data_test
(
data_id number,
data_value varchar2(100),
batch_name varchar2(100)
);
我已将此表用作包含rowid的参数:
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 transform_dat (p_batch_name data_test.batch_name%type);
procedure proc_test (p_dat typ_dat_tst);
end dat_pkg;
/
使用过程transform_dat
,我想用l_dat_rec
表中的过滤记录填充变量data_test
,转换数据,最后使用{{1}更新记录过程:
proc_test
然而我收到错误create or replace package body dat_pkg is
procedure transform_dat (p_batch_name data_test.batch_name%type)
is
cursor cur_dat is
select rowid, a.*
from data_test a
where batch_name = p_batch_name;
l_dat_rec typ_dat_tst;
begin
open cur_dat;
fetch cur_dat
BULK COLLECT
into l_dat_rec;
close cur_dat;
-- Do the Transformation here. Example --
for i in l_dat_rec.count loop
if l_dat_rec(i).data_value = 'hello' then
l_dat_rec(i).data_id := l_dat_rec(i).data_id + l_dat_rec(i).data_id;
else
l_dat_rec(i).data_id := l_dat_rec(i).data_id * l_dat_rec(i).data_id;
end if;
end loop;
-- update the table
proc_test (p_dat => l_dat_rec);
end transform_dat;
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;
/
。使用PLS-00597: expression 'L_DAT_REC' in the INTO list is of wrong type
时会出现同样的错误。
我应该使用什么来填充BULK COLLECT
?
答案 0 :(得分:1)
在上一个问题的答案中,我提到使用%rowtype
字段填充集合会更难。据我所知,除非你声明一个SQL级别的对象类型而不是一个记录类型,否则你不能使用bulk collect
(尽管它有值得检查,如果有的话)也许在12c中改变了。)
我相信你很难使用一个更简单的游标循环来分别构建你的类型中的两个字段(即%rowtype
子字段和rowid
字段),然后构建集合一次一行:
create or replace package body dat_pkg is
procedure transform_dat (p_batch_name data_test.batch_name%type)
is
cursor cur_dat is
select rowid, a.*
from data_test a
where batch_name = p_batch_name;
l_dat_tst typ_dat_tst;
l_rec data_test%rowtype;
begin
for rec_dat in cur_dat loop
l_rec.data_id := rec_dat.data_id;
l_rec.data_value := rec_dat.data_value;
l_rec.batch_name := rec_dat.batch_name;
-- or use a counter you increment for this...
l_dat_tst(l_dat_tst.count + 1).data_rec := l_rec;
l_dat_tst(l_dat_tst.count).data_rowid := rec_dat.rowid;
end loop;
-- Do the Transformation here. Example --
for i in 1..l_dat_tst.count loop
if l_dat_tst(i).data_rec.data_value = 'hello' then
l_dat_tst(i).data_rec.data_value := 'was hello';
else
l_dat_tst(i).data_rec.data_value := 'was not hello';
end if;
end loop;
-- update the table
proc_test (p_dat => l_dat_tst);
end transform_dat;
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_rec.data_value
where data_id = p_dat(i).data_rec.data_id
and rowid = p_dat(i).data_rowid;
end loop;
end proc_test;
end dat_pkg;
/
如前所述,对子字段记录字段的引用必须合格,因此我在两个过程的引用中都插入了.data_rec
。我已经更改了虚拟转换以修改值而不是ID,因为这意味着不会发生任何更新。
使用一些虚拟数据进行演示:
insert into data_test values (1, 'hello', 'test');
insert into data_test values (2, 'hello', 'test');
insert into data_test values (3, 'hello', 'exclude');
insert into data_test values (4, 'goodbye', 'test');
exec dat_pkg.transform_dat('test');
select * from data_test;
DATA_ID DATA_VALUE BATCH_NAME
---------- -------------------- --------------------
1 was hello test
2 was hello test
3 hello exclude
4 was not hello test