【问题标题】:Get Updated or Deleted Record in Oracle Anonymous Block在 Oracle 匿名块中获取更新或删除的记录
【发布时间】:2016-01-28 00:16:39
【问题描述】:

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

我的select语句是这样的:

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 参数以从我的选择中获取数据。

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

如您所知,在 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 的内容?

【问题讨论】:

  • 基本上你的问题是关于C#,与Oracle PL/SQL无关。但你解释得很好,希望有 C# 技能的人可以提供帮助。
  • 不确定这是否有帮助 codeproject.com/Articles/18593/…

标签: c# oracle plsql


【解决方案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;

【讨论】:

  • 那么'RETURNING BULK COLLECT INTO'子句有什么用呢?
  • 如果您想进一步处理到同一个 Oracle 代码块中,这很有用,但您希望将数据返回到调用环境。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多