`
winie
  • 浏览: 223209 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Oracle DML 子句 RETURNING INTO

阅读更多
The RETURNING INTO clause allows us to return column values for rows affected by DML statements. The following test table is used to demonstrate this clause.
DROP TABLE t1;
DROP SEQUENCE t1_seq;

CREATE TABLE t1 (
  id NUMBER(10),
  description VARCHAR2(50),
  CONSTRAINT t1_pk PRIMARY KEY (id)
);

CREATE SEQUENCE t1_seq;

INSERT INTO t1 VALUES (t1_seq.nextval, 'ONE');
INSERT INTO t1 VALUES (t1_seq.nextval, 'TWO');
INSERT INTO t1 VALUES (t1_seq.nextval, 'THREE');
COMMIT;
When we insert data using a sequence to generate our primary key value, we can return the primary key value as follows.
SET SERVEROUTPUT ON
DECLARE
  l_id t1.id%TYPE;
BEGIN
  INSERT INTO t1 VALUES (t1_seq.nextval, 'FOUR')
  RETURNING id INTO l_id;
  COMMIT;

  DBMS_OUTPUT.put_line('ID=' || l_id);
END;
/
ID=4

PL/SQL procedure successfully completed.

SQL>
The syntax is also available for update and delete statements.
SET SERVEROUTPUT ON
DECLARE
  l_id t1.id%TYPE;
BEGIN
  UPDATE t1
  SET    description = description
  WHERE  description = 'FOUR'
  RETURNING id INTO l_id;

  DBMS_OUTPUT.put_line('UPDATE ID=' || l_id);

  DELETE FROM t1
  WHERE  description = 'FOUR'
  RETURNING id INTO l_id;

  DBMS_OUTPUT.put_line('DELETE ID=' || l_id);

  COMMIT;
END;
/
UPDATE ID=4
DELETE ID=4

PL/SQL procedure successfully completed.

SQL>
When DML affects multiple rows we can still use the RETURNING INTO, but now we must return the values into a collection using the BULK COLLECT clause.
SET SERVEROUTPUT ON
DECLARE
  TYPE t_tab IS TABLE OF t1.id%TYPE;
  l_tab t_tab;
BEGIN
  UPDATE t1
  SET    description = description
  RETURNING id BULK COLLECT INTO l_tab;

  FOR i IN l_tab.first .. l_tab.last LOOP
    DBMS_OUTPUT.put_line('UPDATE ID=' || l_tab(i));
  END LOOP;

  COMMIT;
END;
/
UPDATE ID=1
UPDATE ID=2
UPDATE ID=3

PL/SQL procedure successfully completed.

SQL>
We can also use the RETURNING INTO clause in combination with bulk binds.
SET SERVEROUTPUT ON
DECLARE
  TYPE t_desc_tab IS TABLE OF t1.description%TYPE;
  TYPE t_tab IS TABLE OF t1%ROWTYPE;
  l_desc_tab t_desc_tab := t_desc_tab('FIVE', 'SIX', 'SEVEN');
  l_tab   t_tab;
BEGIN
  
  FORALL i IN l_desc_tab.first .. l_desc_tab.last
    INSERT INTO t1 VALUES (t1_seq.nextval, l_desc_tab(i))
    RETURNING id, description BULK COLLECT INTO l_tab;

  FOR i IN l_tab.first .. l_tab.last LOOP
    DBMS_OUTPUT.put_line('INSERT ID=' || l_tab(i).id || 
                         ' DESC=' || l_tab(i).description);
  END LOOP;

  COMMIT;
END;
/
INSERT ID=5 DESC=FIVE
INSERT ID=6 DESC=SIX
INSERT ID=7 DESC=SEVEN

PL/SQL procedure successfully completed.

SQL>
This functionality is also available from dymanic SQL.
SET SERVEROUTPUT ON
DECLARE
  TYPE t_tab IS TABLE OF t1.id%TYPE;
  l_tab t_tab;
BEGIN
  EXECUTE IMMEDIATE 'UPDATE t1
                     SET    description = description
                     RETURNING id INTO :l_tab'
  RETURNING BULK COLLECT INTO l_tab;

  FOR i IN l_tab.first .. l_tab.last LOOP
    DBMS_OUTPUT.put_line('UPDATE ID=' || l_tab(i));
  END LOOP;

  COMMIT;
END;
/
UPDATE ID=1
UPDATE ID=2
UPDATE ID=3

PL/SQL procedure successfully completed.

SQL>
For more information see:
Hope this helps. Regards Tim...

from: http://www.oracle-base.com/articles/misc/dml_returning_into_clause.php

--End--
RETURNING语句几个小问题
2009-11-27 15:23

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语句配合使用的机会更多一些。

分享到:
评论

相关推荐

    oracle RETURNING 子句使用方法

    总的来说,Oracle的RETURNING子句提供了一种高效且灵活的方式,使得在执行DML语句时能够直接获取并利用操作结果,提高了代码的效率和可读性。正确理解和使用这个特性对于编写高效的Oracle数据库应用程序至关重要。

    《Pro Oracle SQL》CHAPTER 9 The Model Clause -- 9.4Returning Updated Rows

    返回更新行的关键在于Model子句的"RETURNING INTO"子句。这个子句允许我们指定一个变量或集合,用来存储Model操作后生成的新行。这使得我们可以进一步处理这些结果,例如插入到其他表中,或者进行额外的分析。 在本...

    Oracle动态SQL之本地动态SQL的使用.pdf

    最后,使用RETURNING INTO子句来处理带有RETURNING子句的非查询DML语句,以便在执行更新或插入操作后获取返回值。 使用动态SQL时还应注意异常处理。当执行动态SQL语句出现问题时,应该捕获异常并处理,比如通过DBMS...

    第十四课Oracle游标和异常处理.pptx

    如果DML语句包含returning子句,如更新或删除后需要获取返回的值,可以使用returning into子句。 游标在Oracle中扮演着重要的角色,尤其是在处理多行结果集时。游标分为显式游标和隐式游标。显式游标需要显式声明、...

    oracle动态函数执行.pdf

    4. **带`RETURNING INTO`子句**: ```sql execute immediate 'sql' returning into var_1; ``` 用于处理单行DML操作(如INSERT, UPDATE, DELETE)的返回值,返回值存入`var_1`。 5. **批量收集**: ```sql ...

    JAVA 与 Sql学习笔记

    在DML语句中使用RETURNING INTO子句,可以将操作结果直接返回到PL/SQL变量中,这对于处理多个返回值非常有用。 7. **Oracle存储过程传入数组**: Oracle允许在存储过程中接收数组参数,这样可以一次性处理多个...

    Oracle知识之集合和成员函数.pptx

    `BULK COLLECT`子句则用于在从SQL引擎返回到PL/SQL引擎之前批量收集结果集,它可以用于`SELECT INTO`,`FETCH INTO`和`RETURNING INTO`子句。 嵌套表是Oracle数据库提供的一种特殊类型的集合,它可以嵌套在另一个表...

    oracleplus编程

    在 PL/SQL 中执行数据操纵语言 (Data Manipulation Language, DML) 语句(如 INSERT、UPDATE 和 DELETE)时,可以使用 RETURNING 子句来检索操作结果。 **3.1 插入记录示例** ```sql DECLARE Row_id ROWID; info ...

    ORACLE资料

    - **RETURNING INTO 子句**:返回数据到指定变量。 #### 子查询 - **标准子查询**:与主查询无直接联系,先于主查询执行。 - **关联子查询**:与主查询有关联,子查询的结果依赖于外部查询提供的值。 #### 表连接...

    pl/sql学习

    `RETURNING INTO`子句则用于将查询结果存储到指定的变量中。 以一个简单的例子来说明动态SQL的使用: 1. 创建名为`emp`的表,插入数据: ```sql CREATE OR REPLACE PROCEDURE create_table AS BEGIN EXECUTE ...

    oracle中动态SQL使用详细介绍

    3. `RETURNING INTO 输出参数列表`:当需要从动态SQL执行结果中获取数据时,可以使用`RETURNING INTO`子句将结果赋值给变量。 以下是一个简单的例子,展示了如何使用动态SQL创建表、查询数据和处理异常: ```sql ...

    批处理 动态sql

    同时,示例还展示了RETURNING BULK COLLECT INTO的用法,它用于在DML操作(如UPDATE、DELETE、INSERT)后获取返回的值,这对于需要获取更新或插入后的新值非常有用。 1. 批处理: - BULK COLLECT INTO:批量收集...

    PL/SQL编程基础知识

    以下示例演示了如何在INSERT语句中使用RETURNING子句来检索刚插入的记录的ROWID和相关信息: ```sql DECLARE Row_id ROWID; info VARCHAR2(40); BEGIN INSERT INTO scott.dept VALUES (90, '财务室', '海口') ...

    PLSQL笔记(EFRIOO&GUOH)1.doc

    返回由最近的 DML 语句影响的行数。 ```sql UPDATE employees SET salary = salary * 1.1 WHERE department_id = 10; DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT); -- 输出受影响的行数 ``` ### 四、事务控制语句 事务控制...

    Merge-Sql.zip

    例如,Oracle的MERGE支持RETURNING子句,允许我们在操作后立即返回新插入或更新的行;而SQL Server则提供了OUTPUT子句,可以捕获受影响的行。了解这些差异对于在跨数据库环境中编写可移植的SQL代码至关重要。 在...

Global site tag (gtag.js) - Google Analytics