ORACLE RETURNING 用法总结
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
注意:
- 多行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
注意:
- returning
into在动态sql内部和外面都要写,且外面的returning后面不加字段直接into。 - using在returning前面
- 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
注意:
- 动态sql内部仍然是returning into而不是returning bulk collect into
- 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 用法总结的更多相关文章
- Oracle instr用法
1:实现indexOf功能,.从第1个字符开始,搜索第1次出现子串的位置 ,) as i from dual; select instr('oracle','or') as i from dual; ...
- Oracle minus用法详解及应用实例
本文转载:https://blog.csdn.net/jhon_03/article/details/78321937 Oracle minus用法 “minus”直接翻译为中文是“减”的意思,在Or ...
- Oracle触发器用法实例详解
转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...
- ORACLE SEQUENCE用法(转)
ORACLE SEQUENCE用法 在oracle中sequence就是序号,每次取的时候它会自动增加.sequence与表没有关系. 1.Create Sequence 首先要有CREATE ...
- [转载]Oracle触发器用法实例详解
本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. 因此触发器不需要人为的去调用,也 ...
- Oracle数据库用法汇总
一些Oracle数据库用法的小总结 1.使用insert into创建新表 insert into destdb.sub_contract (userid,contractid) select msi ...
- Oracle RETURNING INTO 用法示例 .
The RETURNING INTO clause allows us to return column values for rows affected by DML statements. The ...
- oracle sqlloader 用法
向oracle中导入*.csv文件 1.什么是*.csv,如何得到? 里面存放的是数据表.每行代表数据库表格的一行, 每行中,每两个数据中间由逗号","分割. *.csv可以通 ...
- Oracle Hint 用法
正确的语法是: select /*+ index(x idx_t) */ * from t x where x.object_id=123 /*+ */ 和注释很像,比注释多了一个“+”,这就是 ...
随机推荐
- CSharpGL(29)初步封装Texture和Framebuffer
+BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(29)初步封装Texture和Framebuffer +BIT祝威+悄悄在此留下版了个权的信息说: Texture和Framebuffe ...
- Go语言实战 - revel框架教程之缓存和Job
所有的网站应该都会有一个非常简单的需求,首页一秒之内打开. 满足的方式主要有两种: 页面静态化,效果最好,对服务器基本没负担,只要带宽足够就好了.我知道一个PV过亿的站点就是全站静态(以前新浪也是), ...
- springmvc的图片上传与导出显示
1.前端文件上传需要在form表单内添加enctype="multipart/form-data" ,以二进制传递: 2.web.xml文件内配置 <servlet-mapp ...
- HTML&CSS日常知识点总结
HTML 标签 meta 标签永远位于文档的头部,即head元素内部 可提供有关页面的元信息,如针对搜索引擎和更新频度的描述和关键词 charset 这个属性规定在外部脚本文件中使用的字符编码 如果外 ...
- 非阻塞/异步(epoll) openssl
前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定.因此把相关的资料整理一下,并给出简单的例子,让 ...
- ThinkPhp5.0模型验证规则
Tp5提供了模型数据规则的验证功能,用于在数据save或者update前验证数据的有效性.Tp5提供校验规则的类为\Think\Validate,默认提供的校验规则可以查看该文件. 在Model文件中 ...
- [WPF]控件应用多个样式
最近在做WPF项目,公司没有专门的UI工程师,什么都要自己做.接触WPF已经有好几年了,自定义样式什么的也可以做一些.WPF在使用样式的时候一般都是 Style="{StaticResour ...
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...
- ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB
原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...
- 配置Chrome支持本地(file协议)的AJAX请求
什么问题 WEB开发过程中,很多时候我们都是写一些简单的Demo,并不是开发一个完整项目,此时我们常见的操作是: 新建文件夹 新建需要的文件 在Sublime(或其他编辑器)中完成DEMO的编码 双击 ...