是否可以将数组用作合并语句的源
E.g。我有下面的合并语句,当我编译时,我收到错误。 如何使用merge with array作为源表?
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of records
程序代码
CREATE or REPLACE PROCEDURE my_proc (varray IN my_array)
AS
BEGIN
FORALL i IN varray.first..varray.last
MERGE INTO tab t
USING dual
ON ( t.proj_id = varray(i).proj_id)
WHEN MATCHED THEN
UPDATE set
proj_title = varray (i).proj_title
WHERE proj_id = varray (i).proj_id
WHEN NOT MATCHED THEN
insert (proj_id,proj_title)
values (varray (i).proj_id,varray (i).proj_title);
values (varray (i).proj_id,varray (i).proj_title);
答案 0 :(得分:5)
Oracle 10g中存在限制 - 您无法在FORALL
语句中访问单个记录字段。如果您使用的是Oracle 11g,则可以这样做。
但是,有一些解决方法,我推荐以下文章提出其中一些:PLS-00436 in 10g - Workaround。
答案 1 :(得分:2)
这里的问题是您在SET
子句和WHERE
子句中引用了相同的集合。请参阅Oracle Documentation for Forall statement,转到限制部分,第二个项目符号点。
我建议您将varray
集合重命名为不同的内容,因为它是关键字。我还建议你将这个集合分成多个标量集合(varrays或只有一列的嵌套表),然后在你的forall语句中使用这些集合。
答案 2 :(得分:2)
您可以从MERGE
中选择DUAL
子句中的源数据集:
SQL> set serveroutput on
SQL> create table projects (
2 proj_id integer not null primary key,
3 proj_title varchar2(20)
4 );
Table created.
SQL> insert into projects (proj_id, proj_title) values (1, 'Project One');
1 row created.
SQL> insert into projects (proj_id, proj_title) values (2, 'Project Two');
1 row created.
SQL> commit;
Commit complete.
SQL> select *
2 from projects;
PROJ_ID PROJ_TITLE
---------- --------------------
1 Project One
2 Project Two
2 rows selected.
SQL> declare
2 type varray_t is varray(2) of projects%rowtype;
3 arr varray_t;
4 begin
5 with test_data as (select 2 as proj_id, 'New Project Two' as proj_title from dual
6 union all select 3 as proj_id, 'New Project Three' as proj_title from dual)
7 select proj_id, proj_title
8 bulk collect into arr
9 from test_data;
10
11 forall i in arr.first .. arr.last
12 merge into projects
13 using (select arr(i).proj_id as proj_id,
14 arr(i).proj_title as proj_title
15 from dual) mrg
16 on (projects.proj_id = mrg.proj_id)
17 when matched then update set projects.proj_title = mrg.proj_title
18 when not matched then insert (proj_id, proj_title) values (mrg.proj_id, mrg.proj_title);
19
20 dbms_output.put_line(sql%rowcount || ' rows merged');
21
22 commit;
23 end;
24 /
2 rows merged
PL/SQL procedure successfully completed.
SQL> select *
2 from projects;
PROJ_ID PROJ_TITLE
---------- --------------------
1 Project One
2 New Project Two
3 New Project Three
3 rows selected.