在执行INSERT、UPDATE 和 DELETE 语句时,现在我们可以通过RETURNING INTO 子句返回受影响数据的新值或者旧值。
在 Oracle 23c中,INSERT、UPDATE 和 DELETE 语句的 RETURNING INTO 子句得到了增强,可以返回受相应语句影响的旧值和新值。这允许开发人员对每个 DML 类型使用相同的逻辑来获取语句执行前和执行后的值。旧值和新值仅对 UPDATE 语句有效。INSERT 语句不返回旧值,DELETE 语句不返回新值。
作为 SQL 命令执行的一部分,能够获取受 INSERT、UPDATE 和 DELETE 语句影响的旧值和新值,为开发人员提供了读取这些值的统一方法,并减少了数据库必须执行的工作量。
完整的 UPDATE 语法:
其中,RETURNING 子句语法:
你可以为具有单个基表的表、视图和物化视图指定此子句。
当对单行进行操作时,带有returning_clause 的DML 语句可以使用受影响的行、rowid 和受影响行的REF 来检索列值,并将它们存储在主变量或PL/SQL 变量中。
当对多行进行操作时,带有returning_clause 的DML 语句从涉及绑定数组中受影响的行的表达式、rowid 和REF 返回值。
expr
expr 列表中的每一项都必须是有效的表达式语法。
INTO
INTO 子句指示更改的行的值将存储在 data_item 列表中指定的变量中。
data_item
每个 data_item 都是一个主变量或 PL/SQL 变量,用于存储检索到的 expr 值。
对于 RETURNING 列表中的每个表达式,必须在 INTO 列表中指定相应的类型兼容的 PL/SQL 变量或主变量。
给定表中的列 c1 和 c2,您可以为列 c1 指定 OLD(例如 OLD c1)。您还可以为列表达式引用的列指定 OLD(例如 c1 OLD c2)。当列指定OLD时,返回更新前的列值。对于列表达式引用的列,返回的是使用更新前的列值计算列表达式的结果。
可以为列或表达式中引用的列显式指定 NEW 以返回更新后的列值,或使用列更新后值的表达式结果。
当列或表达式中同时省略 OLD 和 NEW 时,将返回更新后列值或使用更新后列值计算的表达式结果。
限制
以下限制适用于 RETURNING 子句:
- expr 的限制如下:
- 对于 UPDATE 和 DELETE 语句,每个 expr 必须是简单表达式或单集聚合函数表达式。您不能在同一个 returned_clause 中组合简单表达式和单集聚合函数表达式。对于 INSERT 语句,每个 expr 必须是一个简单表达式。INSERT 语句 RETURNING 子句中不支持聚合函数。
- 单集聚合函数表达式不能包含 DISTINCT 关键字。
- 如果 expr 列表包含主键列或其他 NOT NULL 列,并且表上定义了 BEFORE UPDATE 触发器,则更新语句将失败。
- 您不能为多表插入指定returning_clause。
- 不能将此子句与并行 DML 或远程对象一起使用。
- 您无法使用此子句检索 LONG 类型。
- 您不能为已定义 INSTEAD OF 触发器的视图指定此子句。
在 UPDATE 中使用 RETURNING 子句示例:
以下示例从更新的行返回值并将结果存储在 PL/SQL 变量 bnd1、bnd2、bnd3 中:
代码语言:javascript复制UPDATE employees
SET job_id ='SA_MAN', salary = salary 1000, department_id = 140
WHERE last_name = 'Jones'
RETURNING salary*0.25, last_name, department_id
INTO :bnd1, :bnd2, :bnd3;
以下示例显示您可以在返回子句的表达式中指定单集聚合函数:
代码语言:javascript复制UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 100
RETURNING SUM(salary) INTO :bnd1;