阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle Returning 语句用法总结

229次阅读
没有评论

共计 4725 个字符,预计需要花费 12 分钟才能阅读完成。

场景

在存储过程、PL/SQL 块里需要返回 INSERT、DELETE、UPDATE、MERGE 等 DML 语句执行后的信息时使用,合理使用 returning 能够简化程序逻辑、提高程序性能。

概述

创建测试表

create table hh_emp_test as select * from scott.emp;

使用 returning 语句

declare

v_empno hh_emp_test.empno%type;

v_ename hh_emp_test.ename%type;

begin

update hh_emp_test set ename=’test’ where empno=7369 returning empno,ename into v_empno,v_ename;

rollback;

dbms_output.put_line(v_empno||’-‘||v_ename);

end;

输出

7369-test

场景分类

dml 修改单行数据

使用方法见概述,此部分较简单,略。

dml 修改多行数据

使用 TABLE 类型

举例:

declare

type v_tp_tab_empno is table of hh_emp_test.empno%type index by pls_integer;

v_tab_empno v_tp_tab_empno;

type v_tp_tab_ename is table of hh_emp_test.ename%type index by pls_integer;

v_tab_ename v_tp_tab_ename;

begin

update hh_emp_test set ename=’test’ where deptno=10 returning empno,ename bulk collect into v_tab_empno,v_tab_ename;

rollback;

for i in 1..v_tab_empno.count loop

dbms_output.put_line(v_tab_empno(i)||’-‘||v_tab_ename(i));

end loop;

end;

输出:

7782-test

7839-test

7934-test

注意:

  1. 多行 returning 须用 bulk collect into

使用 RECORD 类型

示例:

declare

type v_tp_rec is record(empno number,ename varchar2(50));

type v_tp_tab is table of v_tp_rec index by pls_integer;

v_tab v_tp_tab;

begin

update hh_emp_test set ename=’test’ where deptno=10 returning empno,ename bulk collect into v_tab;

rollback;

for i in 1..v_tab.count loop

dbms_output.put_line(v_tab(i).empno||’-‘||v_tab(i).ename);

end loop;

end;

输出:

7782-test

7839-test

7934-test

Dml 修改单行 + 动态 sql

示例:

declare

v_empno hh_emp_test.empno%type;

v_ename hh_emp_test.ename%type;

begin

execute immediate ‘update hh_emp_test set ename=”test” where empno=:empno returning empno,ename into :v_empno,:v_ename’

using 7369

returning into v_empno, v_ename;

rollback;

dbms_output.put_line(v_empno || ‘-‘ || v_ename);

end;

输出:

7369-test

注意:

  1. returning into在动态 sql 内部和外面都要写,且外面的 returning 后面不加字段直接into
  2. usingreturning 前面
  3. into后面变量名不固定,注意冒号(:),可以是命名规则下的任意字符。

dml 修改多行 + 动态 sql

使用 TABLE 类型

示例:

declare

type v_tp_tab_empno is table of hh_emp_test.empno%type index by pls_integer;

v_tab_empno v_tp_tab_empno;

type v_tp_tab_ename is table of hh_emp_test.ename%type index by pls_integer;

v_tab_ename v_tp_tab_ename;

begin

execute immediate ‘update hh_emp_test set ename=”test” where deptno=:deptno returning empno,ename into :v_tab_empno,:v_tab_ename’

using 10

returning bulk collect

into v_tab_empno, v_tab_ename;

rollback;

for i in 1 .. v_tab_empno.count loop

dbms_output.put_line(v_tab_empno(i) || ‘-‘ || v_tab_ename(i));

end loop;

end;

输出:

7782-test

7839-test

7934-test

注意:

  1. 动态 sql 内部仍然是 returning into 而不是 returning bulk collect into
  2. returning bulk collect into 要写在外面,且后面同样不能是 record

使用 RECORD 类型

示例:

declare

type v_tp_rec is record(

empno number,

ename varchar2(50));

type v_tp_tab is table of v_tp_rec index by pls_integer;

v_tab v_tp_tab;

begin

execute immediate ‘update hh_emp_test set ename=”test” where deptno=10 returning empno,ename :v_tab’

returning bulk collect

into v_tab;

rollback;

for i in 1 .. v_tab.count loop

dbms_output.put_line(v_tab(i).empno || ‘-‘ || v_tab(i).ename);

end loop;

end;

执行报错:

ORA-06550: 第 9 行, 第 5 列:

PLS-00429: RETURNING 子句不支持的功能

ORA-06550: 第 8 行, 第 3 列:

PL/SQL: Statement ignored

可见 动态 sql 执行时,多行 returning 的多个字段须定义多个 table 类型的变量,目前为止(包括 12c)不支持 reurning record 类型的语法。

forall 中的 returning

使用 RECORD 类型

示例:

declare

type v_tp_rec is record(

empno number,

ename varchar2(50));

type v_tp_tab is table of v_tp_rec index by pls_integer;

v_tab v_tp_tab;

type t_tp_rec_source is table of hh_emp_test%rowtype index by pls_integer;

t_tab_source t_tp_rec_source;

cursor v_cur is

select * from hh_emp_test;

begin

open v_cur;

fetch v_cur bulk collect

into t_tab_source limit 3;

while t_tab_source.count > 0 loop

forall i in 1 .. t_tab_source.count

update hh_emp_test

set ename = ‘test’

where empno = t_tab_source(i).empno

returning empno, ename bulk collect into v_tab;

rollback;

for i in 1 .. v_tab.count loop

dbms_output.put_line(v_tab(i).empno || ‘-‘ || v_tab(i).ename);

end loop;

fetch v_cur bulk collect

into t_tab_source limit 3;

end loop;

close v_cur;

end;

输出:

7369-test

7499-test

7521-test

7566-test

7654-test

7698-test

7782-test

7839-test

7844-test

7900-test

7902-test

7934-test

使用 TABLE 类型

示例:

declare

type v_tp_tab_empno is table of hh_emp_test.empno%type index by pls_integer;

v_tab_empno v_tp_tab_empno;

type v_tp_tab_ename is table of hh_emp_test.ename%type index by pls_integer;

v_tab_ename v_tp_tab_ename;

type t_tp_rec_source is table of hh_emp_test%rowtype index by pls_integer;

t_tab_source t_tp_rec_source;

cursor v_cur is

select * from hh_emp_test;

begin

open v_cur;

fetch v_cur bulk collect

into t_tab_source limit 3;

while t_tab_source.count > 0 loop

forall i in 1 .. t_tab_source.count

update hh_emp_test

set ename = ‘test’

where empno = t_tab_source(i).empno

returning empno, ename bulk collect into v_tab_empno,v_tab_ename;

rollback;

for i in 1 .. v_tab_empno.count loop

dbms_output.put_line(v_tab_empno(i) || ‘-‘ || v_tab_ename(i));

end loop;

fetch v_cur bulk collect

into t_tab_source limit 3;

end loop;

close v_cur;

end;

输出:

7369-test

7499-test

7521-test

7566-test

7654-test

7698-test

7782-test

7839-test

7844-test

7900-test

7902-test

7934-test

小结:

Forall 的使用和静态 sql dml 修改多行的方法类似。

总结

Oracle Returning 语句随场景不同,语法有变化,要注意动态 sql returning 多行的情况不能使用 record 只能使用 table 类型。

更多 Oracle 相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-09/135457.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计4725字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中