使用 RETURNING INTO 子句和 BULK COLLECT 时如何返回整行

Posted

技术标签:

【中文标题】使用 RETURNING INTO 子句和 BULK COLLECT 时如何返回整行【英文标题】:How to return entire rows when using RETURNING INTO clause and BULK COLLECT 【发布时间】:2018-01-10 20:18:18 【问题描述】:

我正在尝试进行更新,我想返回所有更新的行。这可能吗?我所能找到的只是返回不同表类型中的特定列,但我想将整行收集到一个表类型中并返回该表类型。

我正在尝试使用 Returning Into 子句并可能使用 Bulk Collect

数据库是 Oracle。

【问题讨论】:

【参考方案1】:

让我们考虑一下包含 100 条记录的示例表结构 -

CREATE TABLE TESTT1
(
    ID INTEGER,
    NAME VARCHAR2(100)
);

以下匿名块应该提供所需的功能 -

SET SERVEROUTPUT ON
DECLARE
  TYPE T_TESTT1 IS TABLE OF TESTT1%ROWTYPE;

  L_TESTT1  T_TESTT1;
BEGIN
  UPDATE TESTT1 T
  SET T.NAME = 'Test Message - '||T.ID
  WHERE T.ID < 100
  RETURNING T.ID, T.NAME BULK COLLECT INTO L_TESTT1;

  DBMS_OUTPUT.PUT_LINE('UPDATED ' || L_TESTT1.COUNT || ' ROWS');

  FOR I IN 1 .. L_TESTT1.COUNT
  LOOP
    DBMS_OUTPUT.PUT_LINE('ID= <'|| L_TESTT1(I).ID ||'>, NAME = <'||L_TESTT1(I).NAME||'>');
  END LOOP;

  COMMIT;
END;
/

本示例代码sn-p的输出如下-

UPDATED 99 ROWS
ID= <1>, NAME = <Test Message - 1>
ID= <2>, NAME = <Test Message - 2>
ID= <3>, NAME = <Test Message - 3>
ID= <4>, NAME = <Test Message - 4>
ID= <5>, NAME = <Test Message - 5>
ID= <6>, NAME = <Test Message - 6>
ID= <7>, NAME = <Test Message - 7>
ID= <8>, NAME = <Test Message - 8>
ID= <9>, NAME = <Test Message - 9>
ID= <10>, NAME = <Test Message - 10>
ID= <11>, NAME = <Test Message - 11>
ID= <12>, NAME = <Test Message - 12>
ID= <13>, NAME = <Test Message - 13>
ID= <14>, NAME = <Test Message - 14>
ID= <15>, NAME = <Test Message - 15>
ID= <16>, NAME = <Test Message - 16>
ID= <17>, NAME = <Test Message - 17>
ID= <18>, NAME = <Test Message - 18>
ID= <19>, NAME = <Test Message - 19>
ID= <20>, NAME = <Test Message - 20>
ID= <21>, NAME = <Test Message - 21>
ID= <22>, NAME = <Test Message - 22>
ID= <23>, NAME = <Test Message - 23>
ID= <24>, NAME = <Test Message - 24>
ID= <25>, NAME = <Test Message - 25>
ID= <26>, NAME = <Test Message - 26>
ID= <27>, NAME = <Test Message - 27>
ID= <28>, NAME = <Test Message - 28>
ID= <29>, NAME = <Test Message - 29>
ID= <30>, NAME = <Test Message - 30>
ID= <31>, NAME = <Test Message - 31>
ID= <32>, NAME = <Test Message - 32>
ID= <33>, NAME = <Test Message - 33>
ID= <34>, NAME = <Test Message - 34>
ID= <35>, NAME = <Test Message - 35>
ID= <36>, NAME = <Test Message - 36>
ID= <37>, NAME = <Test Message - 37>
ID= <38>, NAME = <Test Message - 38>
ID= <39>, NAME = <Test Message - 39>
ID= <40>, NAME = <Test Message - 40>
ID= <41>, NAME = <Test Message - 41>
ID= <42>, NAME = <Test Message - 42>
ID= <43>, NAME = <Test Message - 43>
ID= <44>, NAME = <Test Message - 44>
ID= <45>, NAME = <Test Message - 45>
ID= <46>, NAME = <Test Message - 46>
ID= <47>, NAME = <Test Message - 47>
ID= <48>, NAME = <Test Message - 48>
ID= <49>, NAME = <Test Message - 49>
ID= <50>, NAME = <Test Message - 50>
ID= <51>, NAME = <Test Message - 51>
ID= <52>, NAME = <Test Message - 52>
ID= <53>, NAME = <Test Message - 53>
ID= <54>, NAME = <Test Message - 54>
ID= <55>, NAME = <Test Message - 55>
ID= <56>, NAME = <Test Message - 56>
ID= <57>, NAME = <Test Message - 57>
ID= <58>, NAME = <Test Message - 58>
ID= <59>, NAME = <Test Message - 59>
ID= <60>, NAME = <Test Message - 60>
ID= <61>, NAME = <Test Message - 61>
ID= <62>, NAME = <Test Message - 62>
ID= <63>, NAME = <Test Message - 63>
ID= <64>, NAME = <Test Message - 64>
ID= <65>, NAME = <Test Message - 65>
ID= <66>, NAME = <Test Message - 66>
ID= <67>, NAME = <Test Message - 67>
ID= <68>, NAME = <Test Message - 68>
ID= <69>, NAME = <Test Message - 69>
ID= <70>, NAME = <Test Message - 70>
ID= <71>, NAME = <Test Message - 71>
ID= <72>, NAME = <Test Message - 72>
ID= <73>, NAME = <Test Message - 73>
ID= <74>, NAME = <Test Message - 74>
ID= <75>, NAME = <Test Message - 75>
ID= <76>, NAME = <Test Message - 76>
ID= <77>, NAME = <Test Message - 77>
ID= <78>, NAME = <Test Message - 78>
ID= <79>, NAME = <Test Message - 79>
ID= <80>, NAME = <Test Message - 80>
ID= <81>, NAME = <Test Message - 81>
ID= <82>, NAME = <Test Message - 82>
ID= <83>, NAME = <Test Message - 83>
ID= <84>, NAME = <Test Message - 84>
ID= <85>, NAME = <Test Message - 85>
ID= <86>, NAME = <Test Message - 86>
ID= <87>, NAME = <Test Message - 87>
ID= <88>, NAME = <Test Message - 88>
ID= <89>, NAME = <Test Message - 89>
ID= <90>, NAME = <Test Message - 90>
ID= <91>, NAME = <Test Message - 91>
ID= <92>, NAME = <Test Message - 92>
ID= <93>, NAME = <Test Message - 93>
ID= <94>, NAME = <Test Message - 94>
ID= <95>, NAME = <Test Message - 95>
ID= <96>, NAME = <Test Message - 96>
ID= <97>, NAME = <Test Message - 97>
ID= <98>, NAME = <Test Message - 98>
ID= <99>, NAME = <Test Message - 99>


PL/SQL procedure successfully completed.

【讨论】:

当你更新时最好写DBMS_OUTPUT.PUT_LINE('UPDATED ' || L_TESTT1.COUNT || ' ROWS'); 我曾尝试使用删除操作,然后意识到问题针对更新。错过更新输出语句。现已更正。谢谢! 谢谢,但有没有办法让 L_TESTT1 成为返回值?我的应用程序在 ruby​​ 中,我需要通过匿名块(如您以某种方式执行的操作(输出参数?)或通过 plsql 函数)以某种方式将数据返回到 ruby​​。

以上是关于使用 RETURNING INTO 子句和 BULK COLLECT 时如何返回整行的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL v12.6 中的 PLpgSQL INSERT-RETURNING-INTO 错误?

防止 NHibernate 将 Returning 子句添加到生成的插入语句中

为啥我在更新语句后使用 RETURNING 子句时收到“NO DATA FOUND”异常?

在 PHP 中,当将 PDO 与 pgSQL 一起使用时,如何在原始 INSERT sql 查询中获取“RETURNING”子句的值

如何从具有 RETURNING 子句的动态 SQL 返回集合

INSERT INTO table RETURNING 触发器生成的主键从 SQL Server 链接服务器到 Oracle (11g)