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