使用Oracle PL/SQL表类型的MERGE
我想使用MERGE语句创建/更新记录。但得到错误“无效的数据类型”。
表设置
CREATE TABLE ps_test01 (id Number primary key,
name varchar2(30),
active_flag VARCHAR2(1));
CREATE TABLE ps_test02 (id Number primary key,
name varchar2(30));
insert into ps_test01 (id, name, active_flag) values (1, 'test01', 'Y');
insert into ps_test01 (id, name, active_flag) values (2, 'test02', 'Y');
insert into ps_test01 (id, name, active_flag) values (3, 'test03', 'Y');
insert into ps_test02 (id, name) values (1, 'test001');
记录类型
create or replace package test_pkg as
TYPE test_rec IS RECORD
(
id number,
name varchar2(30),
active_flag varchar2(1)
);
TYPE test_tab_type IS TABLE OF test_rec;
end test_pkg;
/
出错的代码
set SERVEROUTPUT on;
declare
l_test varchar(10);
cursor cur_ps_test01 IS
select id, name ,active_flag from ps_test01 where active_flag='Y';
--TYPE test_tab_type is TABLE OF cur_ps_test01%ROWTYPE index by pls_integer;
test_tab test_pkg.test_tab_type;
test_tab2 test_pkg.test_tab_type;
begin
open cur_ps_test01;
fetch cur_ps_test01 bulk collect into test_tab;
close cur_ps_test01;
dbms_output.put_line('number of rows fetched : ' || test_tab.count);
select * bulk collect into test_tab2 from table(test_tab);
dbms_output.put_line('number of rows fetched : ' || test_tab2.count);
merge into ps_test02 tab2 -- error was reported on this line
using ( select id,name,active_flag from table(test_tab) ) tab1
on (tab1.id = tab2.id)
when matched then
update set name = tab1.name
when not matched then
insert (id, name) values (tab1.id, tab1.name);
end;
/
错误
00902. 00000 - "invalid datatype"
*Cause:
*Action:
请帮助我解决此问题。如果你能提出一个更好的方法来做这件事,如果有的话,我很感激。
3条答案
按热度按时间5cg8jx4n1#
Oracle Database 12 c Release 1(12.1)中的更改中列出了对PL/SQL类型使用的限制。
更多纯PL/SQL数据类型可跨PL/SQL转SQL接口
从Oracle Database 12 c开始,可以将仅PL/SQL数据类型的值绑定到匿名块(即SQL语句)、SQL查询和
CALL
语句中的PL/SQL函数调用以及SQL查询中的TABLE
运算符。不过:您可以使用
FORALL
语句从集合执行upsert:| ID|名称|
| - -----|- -----|
| 一个|测试01|
| 2|测试02|
| 3|测试03|
fiddle
但是,如果您不对获取的数据执行任何额外的PL/SQL处理,那么最好将所有内容都保持在SQL级别,并且不要使用上下文切换来移动数据。
g9icjywg2#
作为一个框架挑战,PL/SQL和自定义类型是不必要的,你可以在SQL中完成这一切:
fiddle
我应该能够有多个查询,可以填充
test_tab
,这将有助于我在ps_test02
表中创建/更新记录。如果要使用多个表,则可以使用
UNION ALL
从USING
子句中的多个表中进行选择。l0oc07j23#
创建SQL数据类型而不是PL/SQL数据类型:
然后在DECLARE部分中删除对包的引用:
现在您可以在SQL语句中使用
test_tab
。