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. 小谈Scrum敏捷开发流程

    一晃眼,有两年没有写博客了,回顾前两年,各种奔波,各种忙碌,也有不少的收获.从今天开始,我要把这些收获都分享在这里. 其实这两年,对我影响最大的是开发流程.总所周知,一个好的开发流程,对于项目的进行, ...

  2. 镜像切换Logreader Agent报错:分发数据库中可能存在不一致的状态(续)

    报错: 分发数据库中可能存在不一致的状态: dist_backup_lsn {00000030:000001ba:0004},dist_last_lsn {00000030:000001cd:0004 ...

  3. ABP框架 - 启动配置

    文档目录 本节内容: 配置ABP 替换内置服务 配置模块 为一个模块创建配置 ABP在启动时,提供基础框架和模型来配置和模块化. 置ABP 在预初始化事件中进行配置,示例: kid1412注:XmlL ...

  4. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  5. STM32的入侵检测是干什么用的

    [引]:侵入检测的作用就是监测侵入事件,保护重要的数据不被非法窃取. 你的数据是保存在RAM里的;但是一掉电RAM里的数据就没了;有一块地方,后备电池相关的一块RAM的数据却放不掉(除非电池没电了); ...

  6. CATransition自定义转场动画

    我们可以通过CATransiton来自定义一些漂亮的转场动画, CATransition继承自CAAnimation, 所以用法跟CAAnimation差不多 先直接上一个代码: #import &q ...

  7. Linux 与 Linux Windows 文件共享 小知识

    Linux 与 Linux Windows 文件共享   前提说明:windows主机信息:192.168.1.100 帐号:abc 密码:123 共享文件夹:sharelinux主机信息:192.1 ...

  8. 【java】细说 JAVA中 标注 注解(annotation)

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...

  9. 前端学HTTP之缓存

    前面的话 Web缓存是可以自动保存常见文档副本的HTTP设备.当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取这个文档.本文将详细介绍缓存的相关内容 功能 ...

  10. 前端学HTTP之网络基础

    × 目录 [1]网络 [2]OSI [3]TCP/IP 前面的话 HTTP协议对于前端工程师是非常重要的.我们在浏览网站时,访问的每一个WEB页面都需要使用HTTP协议实现.如果不了解HTTP协议,就 ...