Plsql 在PL/SQL中返回游标中已删除的行

Plsql 在PL/SQL中返回游标中已删除的行,plsql,cursor,sys-refcursor,bulk-collect,Plsql,Cursor,Sys Refcursor,Bulk Collect,我需要在sys\u refcursor中返回已删除的记录。我可以在delete语句之前检索cursor中的数据,但是在delete语句之后是否有方法检索它们?我的意思是,这个过程就像首先删除,然后打开sys\u refcursor获取删除的记录。可能有几个选项,但其中一个选项是使用返回和批量收集。下面是一个简单的例子 CREATE TABLE t ( a NUMBER, b VARCHAR2(10), c DATE ); INSERT INTO t V

我需要在sys\u refcursor中返回已删除的记录。我可以在delete语句之前检索cursor中的数据,但是在delete语句之后是否有方法检索它们?我的意思是,这个过程就像首先删除,然后打开sys\u refcursor获取删除的记录。

可能有几个选项,但其中一个选项是使用
返回
批量收集
。下面是一个简单的例子

CREATE TABLE t (
       a NUMBER,
       b VARCHAR2(10),
       c DATE
);

INSERT INTO t VALUES (1, 'a', SYSDATE);
INSERT INTO t VALUES (2, 'b', SYSDATE);
INSERT INTO t VALUES (3, 'c', SYSDATE);
INSERT INTO t VALUES (4, 'd', SYSDATE);
INSERT INTO t VALUES (5, 'e', SYSDATE);

CREATE OR REPLACE TYPE tt AS OBJECT (
       a NUMBER,
       b VARCHAR2(10),
       c DATE
);

CREATE OR REPLACE TYPE tt_tab AS TABLE OF tt;

DECLARE
  v_tt_tab tt_tab;
  v_tt     tt;
  v_cur    SYS_REFCURSOR;
BEGIN
  DELETE FROM t
   WHERE a < 4
  RETURNING tt(a, b, c) BULK COLLECT INTO v_tt_tab;

  OPEN v_cur FOR
    SELECT tt(a,
              b,
              c)
      FROM TABLE(v_tt_tab);

  LOOP
    FETCH v_cur
      INTO v_tt;
    EXIT WHEN v_cur%NOTFOUND;
  
    dbms_output.put_line(v_tt.a || ' ' || v_tt.b || ' ' || v_tt.c);
  END LOOP;

  CLOSE v_cur;
END;
/

/*
1 a 07-OCT-20
2 b 07-OCT-20
3 c 07-OCT-20
*/

如果计划删除大量行,此选项可能更好。我再次使用了我的
tt
对象,但您确实不需要它。它只是让循环转储
SYS\u REFCURSOR
的内容变得更容易。

我认为应该是另一种方式。如果删除了行,它们就不存在,那么如何检索它们呢?除非有一个数据库触发器将删除的行存储到另一个表中(可能带有时间戳),这样您就可以随心所欲了。
CREATE GLOBAL TEMPORARY TABLE t_gtt (
       a NUMBER,
       b VARCHAR2(10),
       c DATE
);

DECLARE
  v_tt_tab tt_tab;
  v_tt     tt;
  v_cur    SYS_REFCURSOR;
BEGIN
  INSERT INTO t_gtt
    SELECT *
      FROM t
     WHERE a < 4;

  DELETE FROM t
   WHERE EXISTS (SELECT NULL
            FROM t_gtt
           WHERE t_gtt.a = t.a);

  OPEN v_cur FOR
    SELECT tt(a,
              b,
              c)
      FROM t_gtt;

  LOOP
    FETCH v_cur
      INTO v_tt;
    EXIT WHEN v_cur%NOTFOUND;
  
    dbms_output.put_line(v_tt.a || ' ' || v_tt.b || ' ' || v_tt.c);
  END LOOP;

  CLOSE v_cur;
END;
/