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

时间:2015-10-28 09:33:35

标签: c# oracle plsql

我有一个连接到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是Type Oracle.DataAccess.Client.OracleDbType.RefCursor的参数,它使用输出方向添加到我的OracleCommand实例的参数中。

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

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

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

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的内容?

2 个答案:

答案 0 :(得分:1)

您可以在实际删除之前获取要删除到光标中的记录集。当光标打开时,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;

答案 1 :(得分:1)

其中一种方法是使用流水线功能创建包 -

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'))