将SYS_REFCURSOR与CTE一起使用(包括Update语句)

时间:2017-11-15 21:37:41

标签: oracle common-table-expression toad

我正在使用CTE获取一些值,然后使用UPDATE语句清除数据库表中返回的值。

这发生在存储过程中。

UPDATE TABLE1
   SET AA = NULL, BB = NULL
 WHERE EXISTS
          (WITH T1 AS (SELECT AA, BB, CC FROM TABLEABC)
               ,T2
                AS (SELECT AA, BB, CB
                      FROM T1
                     WHERE T1.AA > 100)
           SELECT *
             FROM T2
            WHERE TABLE1.CC = T2.CC

我的专栏BB有一些识别数据,我想在Update语句清除之前捕获它们。任何人都可以指导我如何捕获此列数据并作为过程输出返回。

OPEN SYS_REFCURSOR FOR

1 个答案:

答案 0 :(得分:2)

不幸的是,RETURNING INTO语句的UPDATE子句会在更新之后为您提供值,而不是之前的值。

因此,如果要保存旧值,则必须在UPDATE语句之前执行此操作。请小心锁定行,只实际更新已保存的行,因为您可以在保存数据和更新数据之间修改表。

然后,在ref光标中返回保存的数据。

以下是将所有内容放在一起的代码:

CREATE TABLE TABLE1 ( AA number, BB number );

CREATE OR REPLACE PACKAGE so_test AS

  TYPE TABLE1_LIST_TAB IS TABLE OF TABLE1%ROWTYPE;

  FUNCTION do_it return sys_refcursor;

END so_test;


CREATE OR REPLACE PACKAGE BODY so_test AS

  FUNCTION do_it RETURN SYS_REFCURSOR IS
    l_old_data TABLE1_LIST_TAB;
    l_rc SYS_REFCURSOR;
  BEGIN

    SELECT AA, BB 
    BULK COLLECT INTO l_old_data
    FROM table1
    WHERE -- put your conditions here of what you intend to update
    FOR UPDATE;

    UPDATE TABLE1
      SET AA = NULL, BB = NULL
    WHERE EXISTS ( SELECT 'record old data is captured'
                 FROM   TABLE(l_old_data) od
                 WHERE  od.aa = table1.aa   -- Assuming AA is a primary key
               ) 
    RETURNING AA, BB BULK COLLECT INTO l_old_data;

    OPEN l_rc FOR SELECT * FROM TABLE(l_old_data);

    RETURN l_rc;

  END do_it;
END so_test;

注意:如果您不在12c上,则需要在数据库中将TABLE1_LIST_TAB定义为OBJECT类型而不是在包规范中,否则包体将无法编译。