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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章