将 SYS_REFCURSOR 与 CTE 一起使用(包括 Update 语句)
Use SYS_REFCURSOR with CTE (includes Update statement)
我正在使用 CTE 获取一些值,然后使用 UPDATE 语句从数据库 table.
中清除 returned 值
这是在存储过程中发生的。
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 有一些标识数据,我想在更新语句清除这些数据之前捕获这些数据。谁能指导我如何捕获此列数据并将 return 作为过程输出。
OPEN SYS_REFCURSOR FOR
不幸的是,UPDATE
语句的 RETURNING INTO
子句将为您提供 更新后 的值,而不是先前的值。
所以,如果你想保存旧值,你必须在 UPDATE
语句之前这样做。注意锁定行并且只实际更新您保存的行,因为您的 table 可能会在您保存数据和更新数据之间被修改。
然后,return 将数据保存在一个引用游标中。
这是将所有内容组合在一起的代码:
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
类型,否则包体将不会编译.
我正在使用 CTE 获取一些值,然后使用 UPDATE 语句从数据库 table.
中清除 returned 值这是在存储过程中发生的。
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 有一些标识数据,我想在更新语句清除这些数据之前捕获这些数据。谁能指导我如何捕获此列数据并将 return 作为过程输出。
OPEN SYS_REFCURSOR FOR
不幸的是,UPDATE
语句的 RETURNING INTO
子句将为您提供 更新后 的值,而不是先前的值。
所以,如果你想保存旧值,你必须在 UPDATE
语句之前这样做。注意锁定行并且只实际更新您保存的行,因为您的 table 可能会在您保存数据和更新数据之间被修改。
然后,return 将数据保存在一个引用游标中。
这是将所有内容组合在一起的代码:
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
类型,否则包体将不会编译.