RETURNING语句

先来看结论吧:

1.DELETE的情况,RETURNING返回的肯定是DELETE之前的结果;

  INSERT的情况,RETURNING返回的一定是INSERT之后的结果。

  UPDATE的情况,RETURNING返回的一定是UPDATE之后的结果。

2.RETURNING语句似乎和RETURN通用。(即两个可以相互替换)

3.INSERT INTO VALUES语句支持RETURNING语句,而INSERT INTO SELECT语句不支持。

4.MERGE语句不支持RETURNING语句。

 

 

ORACLEDML语句中可以指定RETURNING语句。RETURNING语句的使用在很多情况下可以简化PL/SQL编程。

这里不打算说明RETURNING语句的使用(其实使用起来也很简单,和SELECT INTO语句没有多大区别。),主要打算说明RETURNING语句的几个特点。

 

 

其实这篇文章源于同事问我的一个问题:

使用UPDATE语句的时候,RETURNING得到的结果是UPDATE之前的结果还是UPDATE之后的结果?

这个问题把我问住了。考虑DELETE的情况,RETURNING返回的肯定是DELETE之前的结果,而考虑INSERT的情况,RETURNING返回的一定是INSERT之后的结果。但是UPDATE到底返回那种情况,就无法推断出来了。而且,由于一般在使用UPDATERETURNING语句时,都会返回主键列,而主键列一般都是不会修改的,因此确实不清楚Oracle返回的是UPDATE之前的结果还是之后的结果。

当然,一个简单的例子就可以测试出来:

SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));

表已创建。

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_NAME VARCHAR2(30);
3 BEGIN
4 INSERT INTO T VALUES (1, 'YANGTK') RETURNING NAME INTO V_NAME;
5 DBMS_OUTPUT.PUT_LINE('INSERT: ' || V_NAME);
6 V_NAME := NULL;
7 UPDATE T SET NAME = 'YTK' RETURNING NAME INTO V_NAME;
8 DBMS_OUTPUT.PUT_LINE('UPDATE: ' || V_NAME);
9 V_NAME := NULL;
10 DELETE T RETURNING NAME INTO V_NAME;
11 DBMS_OUTPUT.PUT_LINE('DELETE: ' || V_NAME);
12 END;
13 /
INSERT: YANGTK
UPDATE: YTK
DELETE: YTK

PL/SQL 过程已成功完成。

显然,UPDATE操作的RETURNING语句是返回UPDATE操作之后的结果。

顺便总结几个RETURNING操作相关的问题:

1RETURNING语句似乎和RETURN通用。

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_NAME VARCHAR2(30);
3 BEGIN
4 INSERT INTO T VALUES (1, 'YANGTK') RETURN NAME INTO V_NAME;
5 DBMS_OUTPUT.PUT_LINE('INSERT: ' || V_NAME);
6 V_NAME := NULL;
7 UPDATE T SET NAME = 'YTK' RETURN NAME INTO V_NAME;
8 DBMS_OUTPUT.PUT_LINE('UPDATE: ' || V_NAME);
9 V_NAME := NULL;
10 DELETE T RETURN NAME INTO V_NAME;
11 DBMS_OUTPUT.PUT_LINE('DELETE: ' || V_NAME);
12 END;
13 /
INSERT: YANGTK
UPDATE: YTK
DELETE: YTK

PL/SQL 过程已成功完成。

2RETURNING语句也可以使用SQLPLUS的变量,这样,RETURNING语句不一定非要用在PL/SQL语句中。

SQL> VAR V_NAME VARCHAR2(30)
SQL> INSERT INTO T VALUES (1, 'YANGTK') RETURNING NAME INTO :V_NAME;

已创建 1 行。

SQL> PRINT V_NAME

V_NAME
--------------------------------
YANGTK

SQL> UPDATE T SET NAME = 'YTK' RETURNING NAME INTO :V_NAME;

已更新 1 行。

SQL> PRINT V_NAME

V_NAME
--------------------------------
YTK

SQL> DELETE T RETURNING NAME INTO :V_NAME;

已删除 1 行。

SQL> PRINT V_NAME

V_NAME
--------------------------------
YTK

3INSERT INTO VALUES语句支持RETURNING语句,而INSERT INTO SELECT语句不支持。MERGE语句不支持RETURNING语句。

SQL> MERGE INTO T USING (SELECT * FROM T) T1
2 ON (T.ID = T1.ID)
3 WHEN MATCHED THEN UPDATE SET NAME = T1.NAME
4 WHEN NOT MATCHED THEN INSERT VALUES (T1.ID, T1.NAME)
5 RETURNING NAME INTO :V_NAME;
RETURNING NAME INTO :V_NAME
*
5 行出现错误:
ORA-00933: SQL
命令未正确结束


SQL> INSERT INTO T SELECT * FROM T RETURNING NAME INTO :V_NAME;
INSERT INTO T SELECT * FROM T RETURNING NAME INTO :V_NAME
*
1 行出现错误:
ORA-00933: SQL
命令未正确结束

这两个限制确实不大方便。不知道Oracle在以后版本中是否会放开。

个人感觉RETURNING语句和BULK COLLECT INTO语句配合使用的机会更多一些。

 

 

 

 

原文出处:http://yangtingkun.itpub.net/post/468/93315

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值