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);
IXDBA.NET技术社区
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中使用动态SQL进行表的操作和数据查询。 假设有一个员工表`emp`,包含字段`ID`、`NAME`和`SALARY`。 1. **创建表**:首先使用动态SQL创建这个表。 ```sql ...
例如,MySQL的`LAST_INSERT_ID()`在Oracle中可能需要使用`RETURNING INTO`语句。 5. **性能优化**:Oracle提供了许多高级特性,如分区、物化视图、索引等,用于提升性能。迁移后,根据业务需求对新数据库进行性能...
接下来,通过几个具体示例来展示如何使用动态SQL解决实际问题。 **示例一:创建表并插入数据** 首先,创建一个名为`EMP`的表,并向其中插入数据。 ```sql CREATE OR REPLACE PROCEDURE CREATE_TABLE AS BEGIN ...
在这里,`empty_clob()`函数用于创建一个空的CLOB对象,然后通过`RETURNING`子句返回,以便于iBATIS能够填充到Java对象中。 3. **更新操作**:更新CLOB字段时,通常需要先获取原始的CLOB对象,然后用新的值覆盖。...
根据提供的文件信息,我们可以深入探讨Oracle PL/SQL性能调优中的关键知识点,这些知识点主要集中在“编码实践”和“系统配置”两个方面。 ### 一、编码实践 #### 数值数据类型的选择 在PL/SQL中,数值数据类型的...
在Oracle数据库环境中,存储过程是一种重要的数据库对象,它允许开发者将一组SQL语句和控制流程语句封装在一个命名单元中,从而实现更复杂、更高效的数据处理逻辑。本文将深入探讨Oracle存储过程的创建、参数传递、...
Oracle数据库中的动态函数执行是PL/SQL编程中的一项重要特性,它允许在运行时构建和执行SQL语句或存储过程。动态SQL的核心在于`EXECUTE IMMEDIATE`语句,这使得开发者能够在不知道具体SQL结构或者需要根据运行时的...
根据提供的文件信息,我们可以总结出以下几个关键的Oracle数据库性能优化及数据维护相关的知识点: ### 一、函数优化与索引创建 #### 函数优化 在文件的部分内容中,出现了两个相似的函数`f1`和`f2`,这两个函数的...
在实践过程中,主要经历了以下几个步骤: 1. **实践评估**:对项目的可行性进行分析,并评估所需的工作量,包括对现有系统的影响和改造难度。 2. **制定方案**:明确迁移的重点和难点,制定详尽的迁移策略,包括...
动态SQL的基本开发流程包括以下几个步骤: 1. 使用`EXECUTE IMMEDIATE`语句构建动态SQL字符串,可以包含参数占位符。 2. 提供输入参数列表(using子句),用于在运行时绑定到动态SQL中的占位符。 3. 可选地,可以...
5. MERGE INTO语句的改造:在PostgreSQL中,需使用with子句、update returning及insert来实现类似的功能。 通过这些实践,阿里数据库团队成功地将Oracle替换为PostgreSQL,降低了运维成本,提高了系统的自主可控性...
在PL/SQL环境中可以使用的SQL语句主要包括以下几种: - **INSERT**:用于向表中插入新记录。 - **UPDATE**:用于更新现有记录。 - **DELETE**:用于删除表中的记录。 - **SELECT INTO**:用于从表中选取数据,并将...
标题中的问题直指一个常见的编程疑难点:在使用VB(Visual Basic)进行数据库操作时,通过ExecuteNonQuery方法调用存储过程,但返回值总是-1。这个问题可能涉及到多个知识点,包括VB.NET的数据访问机制、ADO.NET组件...