ORACLE RETURNING 用法总结

场景

在存储过程、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. using在returning前面
  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 RETURNING 用法总结的更多相关文章

  1. Oracle instr用法

    1:实现indexOf功能,.从第1个字符开始,搜索第1次出现子串的位置 ,) as i from dual; select instr('oracle','or') as i from dual; ...

  2. Oracle minus用法详解及应用实例

    本文转载:https://blog.csdn.net/jhon_03/article/details/78321937 Oracle minus用法 “minus”直接翻译为中文是“减”的意思,在Or ...

  3. Oracle触发器用法实例详解

    转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...

  4. ORACLE SEQUENCE用法(转)

    ORACLE SEQUENCE用法 在oracle中sequence就是序号,每次取的时候它会自动增加.sequence与表没有关系. 1.Create Sequence     首先要有CREATE ...

  5. [转载]Oracle触发器用法实例详解

    本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. 因此触发器不需要人为的去调用,也 ...

  6. Oracle数据库用法汇总

    一些Oracle数据库用法的小总结 1.使用insert into创建新表 insert into destdb.sub_contract (userid,contractid) select msi ...

  7. Oracle RETURNING INTO 用法示例 .

    The RETURNING INTO clause allows us to return column values for rows affected by DML statements. The ...

  8. oracle sqlloader 用法

    向oracle中导入*.csv文件   1.什么是*.csv,如何得到? 里面存放的是数据表.每行代表数据库表格的一行, 每行中,每两个数据中间由逗号","分割. *.csv可以通 ...

  9. Oracle Hint 用法

    正确的语法是: select /*+ index(x idx_t) */ * from t x where x.object_id=123 /*+    */ 和注释很像,比注释多了一个“+”,这就是 ...

随机推荐

  1. 模拟实现Spring中的注解装配

    本文原创,地址为http://www.cnblogs.com/fengzheng/p/5037359.html 在Spring中,XML文件中的bean配置是实现Spring IOC的核心配置文件,在 ...

  2. CSharpGL(35)用ViewPort实现类似3DMax那样的把一个场景渲染到4个视口

    CSharpGL(35)用ViewPort实现类似3DMax那样的把一个场景渲染到4个视口 开始 像下面这样的四个视口的功能是很常用的,所以我花了几天时间在CSharpGL中集成了这个功能. 在CSh ...

  3. Java中六大时间类的使用和区别

    关于java中六个时间类的使用和区别 java.util.Date java.sql.Date  java.sql.Time  java.sql.Timestamp java.text.SimpleD ...

  4. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  5. BootStrap_01之全局样式

    1.响应式网页: ①Responsive Web Page:一个可以根据浏览设备的不同,而自动更改布局.图片.文字效果的网页: ②构成:不能固定宽度,必须流式布局:文字和图片大小随容器大小而改变:CS ...

  6. 利用select实现IO多路复用TCP服务端

    一.相关函数 1.  int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeva ...

  7. JavaScript:让浏览器全屏显示

    并不是所有人都会按F11让浏览器全屏显示~~~ 一.直接上代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xh ...

  8. boost::function的用法

    本片文章主要介绍boost::function的用法. boost::function 就是一个函数的包装器(function wrapper),用来定义函数对象. 1.  介绍 Boost.Func ...

  9. Vertica增加一个数据存储的目录

    Vertica增加一个数据存储的目录 操作语法为: ADD_LOCATION ( 'path' , [ 'node' , 'usage', 'location_label' ] ) 各节点添加目录,并 ...

  10. 中文分词工具探析(二):Jieba

    1. 前言 Jieba是由fxsjy大神开源的一款中文分词工具,一款属于工业界的分词工具--模型易用简单.代码清晰可读,推荐有志学习NLP或Python的读一下源码.与采用分词模型Bigram + H ...