在Oracle匿名块中获取更新或删除的记录

本文关键字:更新 删除 记录 获取 Oracle | 更新日期: 2023-09-27 18:19:39

我有一个连接到Oracle数据库的C#应用程序。我动态生成PL''SQL语句,并使用CommandType=Text执行它们(我不使用SP)。

我的选择语句如下:

DECLARE
  -- <declaring>
BEGIN
  -- <some PL'SQL code>
  OPEN :refCursor FOR SELECT * FROM tablename
  -- <some PL'SQL code>
END;

在我的C#代码中,refCorsor是一个类型为Oracle.DataAccess.Client.OracleDbType.RefCursor的参数,它使用输出方向添加到我的OracleCommand实例的参数中。

在ExecuteNonQuery调用返回后,我读取refCorsor参数以从select中获取数据。

我的问题是,当我想使用RETURNING BULK COLLECT INTO子句在Oracle中获取已删除的记录时。

如您所知,在Oracle中,RETURNING BULK COLLECT INTO子句可以用于在delete语句之后获取已删除记录的列。此子句将数据放入集合中。

DECLARE
  TYPE RecordType IS RECORD("Id" INT,"Name" nvarchar2(50));
  TYPE IdsTableType IS TABLE OF RecordType;
  IdsName IdsTableType;
BEGIN
  DELETE FROM  "dbo"."AutoInt" WHERE "Name"='aaaa'
  returning "Id","Name"  BULK COLLECT INTO IdsName;
END;

问题是如何从C#代码中读取IdsName的内容?

在Oracle匿名块中获取更新或删除的记录

您可以在实际删除之前将要删除的记录集提取到光标中。当光标打开时,记录的状态将由Oracle维护。

DECLARE
  -- <declaring>
BEGIN
  -- <some PL'SQL code>
  OPEN :refCursor FOR SELECT * FROM "AutoInt" WHERE "Name"='aaaa';
  DELETE FROM  "AutoInt" WHERE "Name"='aaaa';
  -- <some PL'SQL code>
END;

其中一种方法是创建具有流水线功能的包-

CREATE OR REPLACE package pkg_records as
    TYPE RecordType IS RECORD("Id" INT,"Name" nvarchar2(50));
    TYPE IdsTableType IS TABLE OF RecordType;
    function delete_auto_int RETURN IdsTableType PIPELINED;
END pkg_records;
/
CREATE OR REPLACE package body pkg_records as
    function delete_auto_int(name_ in varchar2) RETURN IdsTableType PIPELINED is
    PRAGMA AUTONOMOUS_TRANSACTION;
    IdsName IdsTableType;
    BEGIN
      DELETE FROM  "dbo"."AutoInt" WHERE "Name"= name_
      returning "Id","Name" BULK COLLECT INTO IdsName;
      commit;
      if IdsName.count > 0 then
          for i in IdsName.FIRST..IdsName.LAST loop
            pipe ROW(IdsName(i));
          end loop;
       end if;
    END;
END pkg_records;
/

然后只需使用简单的选择-

select * from table(pkg_records.delete_auto_int('aaaa'))