ORACLE的DML语句中可以指定RETURNING语句。RETURNING语句的使用在很多情况下可以简化PL/SQL编程。
这里不打算说明RETURNING语句的使用(其实使用起来也很简单,和SELECT INTO语句没有多大区别。),主要打算说明RETURNING语句的几个特点。
其实这篇文章源于同事问我的一个问题:
使用UPDATE语句的时候,RETURNING得到的结果是UPDATE之前的结果还是UPDATE之后的结果?
这个问题把我问住了。考虑DELETE的情况,RETURNING返回的肯定是DELETE之前的结果,而考虑INSERT的情况,RETURNING返回的一定是INSERT之后的结果。但是UPDATE到底返回那种情况,就无法推断出来了。而且,由于一般在使用UPDATE的RETURNING语句时,都会返回主键列,而主键列一般都是不会修改的,因此确实不清楚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操作相关的问题:
1.RETURNING语句似乎和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 过程已成功完成。
2.RETURNING语句也可以使用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
3.INSERT 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子句提供了一种高效且灵活的方式,使得在执行DML语句时能够直接获取并利用操作结果,提高了代码的效率和可读性。正确理解和使用这个特性对于编写高效的Oracle数据库应用程序至关重要。
返回更新行的关键在于Model子句的"RETURNING INTO"子句。这个子句允许我们指定一个变量或集合,用来存储Model操作后生成的新行。这使得我们可以进一步处理这些结果,例如插入到其他表中,或者进行额外的分析。 在本...
最后,使用RETURNING INTO子句来处理带有RETURNING子句的非查询DML语句,以便在执行更新或插入操作后获取返回值。 使用动态SQL时还应注意异常处理。当执行动态SQL语句出现问题时,应该捕获异常并处理,比如通过DBMS...
如果DML语句包含returning子句,如更新或删除后需要获取返回的值,可以使用returning into子句。 游标在Oracle中扮演着重要的角色,尤其是在处理多行结果集时。游标分为显式游标和隐式游标。显式游标需要显式声明、...
4. **带`RETURNING INTO`子句**: ```sql execute immediate 'sql' returning into var_1; ``` 用于处理单行DML操作(如INSERT, UPDATE, DELETE)的返回值,返回值存入`var_1`。 5. **批量收集**: ```sql ...
在DML语句中使用RETURNING INTO子句,可以将操作结果直接返回到PL/SQL变量中,这对于处理多个返回值非常有用。 7. **Oracle存储过程传入数组**: Oracle允许在存储过程中接收数组参数,这样可以一次性处理多个...
`BULK COLLECT`子句则用于在从SQL引擎返回到PL/SQL引擎之前批量收集结果集,它可以用于`SELECT INTO`,`FETCH INTO`和`RETURNING INTO`子句。 嵌套表是Oracle数据库提供的一种特殊类型的集合,它可以嵌套在另一个表...
在 PL/SQL 中执行数据操纵语言 (Data Manipulation Language, DML) 语句(如 INSERT、UPDATE 和 DELETE)时,可以使用 RETURNING 子句来检索操作结果。 **3.1 插入记录示例** ```sql DECLARE Row_id ROWID; info ...
- **RETURNING INTO 子句**:返回数据到指定变量。 #### 子查询 - **标准子查询**:与主查询无直接联系,先于主查询执行。 - **关联子查询**:与主查询有关联,子查询的结果依赖于外部查询提供的值。 #### 表连接...
`RETURNING INTO`子句则用于将查询结果存储到指定的变量中。 以一个简单的例子来说明动态SQL的使用: 1. 创建名为`emp`的表,插入数据: ```sql CREATE OR REPLACE PROCEDURE create_table AS BEGIN EXECUTE ...
3. `RETURNING INTO 输出参数列表`:当需要从动态SQL执行结果中获取数据时,可以使用`RETURNING INTO`子句将结果赋值给变量。 以下是一个简单的例子,展示了如何使用动态SQL创建表、查询数据和处理异常: ```sql ...
同时,示例还展示了RETURNING BULK COLLECT INTO的用法,它用于在DML操作(如UPDATE、DELETE、INSERT)后获取返回的值,这对于需要获取更新或插入后的新值非常有用。 1. 批处理: - BULK COLLECT INTO:批量收集...
以下示例演示了如何在INSERT语句中使用RETURNING子句来检索刚插入的记录的ROWID和相关信息: ```sql DECLARE Row_id ROWID; info VARCHAR2(40); BEGIN INSERT INTO scott.dept VALUES (90, '财务室', '海口') ...
返回由最近的 DML 语句影响的行数。 ```sql UPDATE employees SET salary = salary * 1.1 WHERE department_id = 10; DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT); -- 输出受影响的行数 ``` ### 四、事务控制语句 事务控制...
例如,Oracle的MERGE支持RETURNING子句,允许我们在操作后立即返回新插入或更新的行;而SQL Server则提供了OUTPUT子句,可以捕获受影响的行。了解这些差异对于在跨数据库环境中编写可移植的SQL代码至关重要。 在...