Sql 将循环中的多行追加到out参数

Sql 将循环中的多行追加到out参数,sql,oracle,plsql,database-cursor,Sql,Oracle,Plsql,Database Cursor,我需要备份所有将被以下代码删除的记录。为此,我试图用select*替换所有的delete命令,并使用jdbc结果集将其保存到一个文件中,但我被困在下面的代码段中,其中记录被标记,然后在循环中被删除。我曾尝试使用select..in和…exist语句扩展此逻辑,但查询处理时间太长,可能会在生产中失败。我还尝试使用sys\u refcursor,但问题是delete在循环中,无法更新光标。因此,基本要求是如何将以下代码删除的所有记录存储在out_参数中并返回它。请帮忙!谢谢 DECLARE

我需要备份所有将被以下代码删除的记录。为此,我试图用
select*
替换所有的delete命令,并使用jdbc结果集将其保存到一个文件中,但我被困在下面的代码段中,其中记录被标记,然后在循环中被删除。我曾尝试使用
select..in和…exist
语句扩展此逻辑,但查询处理时间太长,可能会在生产中失败。我还尝试使用
sys\u refcursor
,但问题是
delete
在循环中,无法更新光标。因此,基本要求是如何将以下代码删除的所有记录存储在out_参数中并返回它。请帮忙!谢谢

DECLARE 
    CURSOR purger(p_reference IN VARCHAR2) IS
        SELECT DISTINCT id, reference, PARENT, LEVEL
        FROM table ps1
        START WITH ps1.reference = p_reference
        CONNECT BY PRIOR ps1.reference = ps1.parent;
BEGIN
FOR i IN (SELECT DISTINCT reference
                FROM table
                WHERE PARENT IS NULL)
      LOOP
        l_level  := 'N';
        FOR j IN purger(i.reference)
        LOOP
          IF j.level > 1
          THEN
            l_level := 'Y';
          END IF;
        END LOOP;
        IF l_level = 'N'
        THEN
          DELETE FROM tale WHERE reference = i.reference;
        END IF;
        IF l_level = 'Y'
        THEN
          DELETE FROM table
          WHERE id IN (SELECT DISTINCT id
                       FROM table ps1
                       START WITH ps1.reference = i.reference
                       CONNECT BY PRIOR ps1.reference = ps1.parent);
        END IF;
      END LOOP;
END

声明主键的集合。无论何时删除行,都会在临时集合中存储id列表。将其元素添加到主集合中。“全部删除后”,主集合具有已删除的所有主键值。您可以返回此集合、回滚和显示行。希望这有帮助

测试数据:

create table test (id, col) as 
  select 1, 'P' from dual union all
  select 2, 'Q' from dual union all
  select 3, 'Z' from dual;
代码块:

declare 
  va sys.odcinumberlist := sys.odcinumberlist();
  vb sys.odcinumberlist;
begin
  -- first delete
  delete from test where col in ('Z') returning id bulk collect into vb;
  -- add deleted ids to VA
  for i in 1..vb.count loop va.extend; va(va.last) := vb(i); end loop;

  -- second delete
  delete from test where col in ('P', 'Z') returning id bulk collect into vb;
  -- add deleted ids to VA
  for i in 1..vb.count loop va.extend; va(va.last) := vb(i); end loop;

  -- variable VA has all deleted ids
  -- you can rollback and show deleted rows if you want

  rollback;
  for rec in (select * from test where id in (select * from table(va))) loop
    dbms_output.put_line(rec.id||' '||rec.col);
  end loop;
end;

您是否考虑过为要删除记录的表创建触发器?ON DELETE触发器可能首先将要删除的记录插入一个单独的表中。不幸的是,由于时间和流程限制,目前无法进行任何数据库端更改。因此,我正在尝试将此删除查询转换为选择查询,并在匿名块中运行它。我只需要帮助将此循环转换为选择查询。