INSERT、UPDATE 和 DELETE 命令可以附加可选的 RETURNING INTO 子句。此子句允许 SPL 程序分别从 INSERT、UPDATE 或 DELETE 命令的结果中捕获新添加的、修改的或删除的值。

以下是语法。

{ insert | update | delete }
  RETURNING { * | expr_1 [, expr_2 ] ...}
    INTO { record | field_1 [, field_2 ] ...};

insert 是有效的 INSERT 命令。update 是有效的 UPDATE 命令。delete 是有效的 DELETE 命令。如果指定了 *,则来自受 INSERT、UPDATE 或 DELETE 命令影响的行的值可赋给 INTO 关键字右侧的记录或字段。(请注意,使用 * 是PolarDB PostgreSQL版(兼容Oracle)的扩展,与 Oracle 数据库不兼容。)expr_1, expr_2... 是根据受 INSERT、UPDATE 或 DELETE 命令影响的行计算的表达式。将计算结果赋给 INTO 关键字右侧的记录或字段。record 是必须包含在数量和顺序方面匹配且其数据类型与 RETURNING 子句中的值兼容的字段的记录的标识符。field_1, field_2,... 是必须在数量和顺序方面匹配且其数据类型与 RETURNING 子句中的值集兼容的变量。

如果 INSERT、UPDATE 或 DELETE 命令返回包含多行的结果集,则会引发异常并显示 SQLCODE 01422, query returned more than one row。如果结果集中没有任何行,则 INTO 关键字后面的变量将设置为 null。

说明 有一个使用 BULK COLLECT 子句的 RETURNING INTO 变体,它允许包含返回到集合中的多行的结果集。

以下示例修改UPDATE中介绍的 emp_comp_update 存储过程,添加了 RETURNING INTO 子句。

CREATE OR REPLACE PROCEDURE emp_comp_update (
    p_empno         IN emp.empno%TYPE,
    p_sal           IN emp.sal%TYPE,
    p_comm          IN emp.comm%TYPE
)
IS
    v_empno         emp.empno%TYPE;
    v_ename         emp.ename%TYPE;
    v_job           emp.job%TYPE;
    v_sal           emp.sal%TYPE;
    v_comm          emp.comm%TYPE;
    v_deptno        emp.deptno%TYPE;
BEGIN
    UPDATE emp SET sal = p_sal, comm = p_comm WHERE empno = p_empno
    RETURNING
        empno,
        ename,
        job,
        sal,
        comm,
        deptno
    INTO
        v_empno,
        v_ename,
        v_job,
        v_sal,
        v_comm,
        v_deptno;

    IF SQL%FOUND THEN
        DBMS_OUTPUT.PUT_LINE('Updated Employee # : ' || v_empno);
        DBMS_OUTPUT.PUT_LINE('Name               : ' || v_ename);
        DBMS_OUTPUT.PUT_LINE('Job                : ' || v_job);
        DBMS_OUTPUT.PUT_LINE('Department         : ' || v_deptno);
        DBMS_OUTPUT.PUT_LINE('New Salary         : ' || v_sal);
        DBMS_OUTPUT.PUT_LINE('New Commission     : ' || v_comm);
    ELSE
        DBMS_OUTPUT.PUT_LINE('Employee # ' || p_empno || ' not found');
    END IF;
END;

以下是此存储过程的输出(假定 emp_insert 存储过程创建的员工 9503 仍存在于表中)。

EXEC emp_comp_update(9503, 6540, 1200);

Updated Employee # : 9503
Name               : PETERSON
Job                : ANALYST
Department         : 40
New Salary         : 6540.00
New Commission     : 1200.00

以下示例修改 emp_delete 存储过程,使用记录类型添加了 RETURNING INTO 子句。

CREATE OR REPLACE PROCEDURE emp_delete (
    p_empno         IN emp.empno%TYPE
)
IS
    r_emp           emp%ROWTYPE;
BEGIN
    DELETE FROM emp WHERE empno = p_empno
    RETURNING
        *
    INTO
        r_emp;

    IF SQL%FOUND THEN
        DBMS_OUTPUT.PUT_LINE('Deleted Employee # : ' || r_emp.empno);
        DBMS_OUTPUT.PUT_LINE('Name               : ' || r_emp.ename);
        DBMS_OUTPUT.PUT_LINE('Job                : ' || r_emp.job);
        DBMS_OUTPUT.PUT_LINE('Manager            : ' || r_emp.mgr);
        DBMS_OUTPUT.PUT_LINE('Hire Date          : ' || r_emp.hiredate);
        DBMS_OUTPUT.PUT_LINE('Salary             : ' || r_emp.sal);
        DBMS_OUTPUT.PUT_LINE('Commission         : ' || r_emp.comm);
        DBMS_OUTPUT.PUT_LINE('Department         : ' || r_emp.deptno);
    ELSE
        DBMS_OUTPUT.PUT_LINE('Employee # ' || p_empno || ' not found');
    END IF;
END;

以下是此存储过程的输出。

EXEC emp_delete(9503);

Deleted Employee # : 9503
Name               : PETERSON
Job                : ANALYST
Manager            : 7902
Hire Date          : 31-MAR-05 00:00:00
Salary             : 6540.00
Commission         : 1200.00
Department         : 40