Oracle-在过程中选择并删除
我需要从Oracle过程返回一个行集,然后在同一过程中删除它们。没有临时表,有没有一种简洁的方法?可能是内存中的光标Oracle-在过程中选择并删除,oracle,plsql,Oracle,Plsql,我需要从Oracle过程返回一个行集,然后在同一过程中删除它们。没有临时表,有没有一种简洁的方法?可能是内存中的光标 基本上,我是从队列中弹出记录,我希望避免两次往返,因为这是一个非常频繁的过程。您可以使用光标进行更新,例如 DECLARE CURSOR c_updates IS SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.field = t2.field WHERE t2.field IS NULL
基本上,我是从队列中弹出记录,我希望避免两次往返,因为这是一个非常频繁的过程。您可以使用光标进行更新,例如
DECLARE
CURSOR c_updates
IS
SELECT *
FROM table1 t1
LEFT JOIN table2 t2 ON t1.field = t2.field
WHERE t2.field IS NULL
FOR UPDATE OF t1.field;
l_record c_updates%ROWTYPE;
BEGIN
OPEN c_updates;
LOOP
FETCH c_updates INTO l_record;
EXIT WHEN c_updates%NOTFOUND;
--Do what you want with l_record
DELETE FROM table1
WHERE CURRENT OF c_updates;
END LOOP;
CLOSE c_updates;
END;
将数据填充到类型中并返回该类型 e、 g 基于和: 警告:我目前没有访问PL/SQL编译器的权限,因此有可能出现问题
TYPE popped_records_table_type IS TABLE OF my_table%ROWTYPE INDEX BY BINARY_INTEGER;
FUNCTION pop_records(...) RETURN popped_records_table_type IS
popped_records popped_records_table_type;
popped_record my_table%ROWTYPE;
next_popped_record_index BINARY_INTEGER;
CURSOR popped_records_cursor IS
SELECT * FROM my_table WHERE ... FOR UPDATE;
BEGIN
next_popped_record_index := 1;
OPEN popped_records_cursor;
LOOP
FETCH popped_records_cursor INTO popped_record;
EXIT WHEN popped_records_cursor%NOTFOUND;
DELETE FROM my_table WHERE CURRENT OF popped_records_cursor;
popped_records(next_popped_record_index) := popped_record;
next_popped_record_index := next_popped_record_index + 1;
END LOOP;
CLOSE popped_records_cursor;
RETURN popped_records;
END;
编辑:我相信这也适用于存储过程,只要您提供弹出的\u记录\u表\u类型的实例作为输入/输出参数:
PROCEDURE pop_records(popped_records IN OUT popped_records_table_type, ...) IS
-- Pretty much the same as above
可以从过程或匿名块返回光标:
BEGIN
OPEN :cur FOR
SELECT *
FROM table
WHERE condition;
DELETE
FROM table
WHERE condition;
END;
删除后光标将保持不变
有关详细说明,请参见我的博客中的条目:
CREATE TABLE t_deleter (id INT NOT NULL PRIMARY KEY, value VARCHAR2(50))
/
INSERT
INTO t_deleter (id, value)
VALUES (1, 'Value 1')
/
INSERT
INTO t_deleter (id, value)
VALUES (2, 'Value 2')
/
COMMIT
/
SELECT *
FROM t_deleter
/
VAR cur REFCURSOR
BEGIN
OPEN :cur FOR
SELECT *
FROM t_deleter
WHERE id = 1;
DELETE
FROM t_deleter
WHERE id = 1;
END;
/
PRINT cur
SELECT *
FROM t_deleter
/
Table created.
1 row created.
1 row created.
Commit complete.
ID VALUE
---------- --------------------------------------------------
1 Value 1
2 Value 2
PL/SQL procedure successfully completed.
/*
PRINT CUR
This is what returned to the client
*/
ID VALUE
---------- --------------------------------------------------
1 Value 1
/*
SELECT *
FROM t_deleter
This is what's left after the procedure completed
*/
ID VALUE
---------- --------------------------------------------------
2 Value 2
事实上,这些天你不用选择就可以做到。您只需删除感兴趣的记录,并在删除记录时使用RETURNING子句将这些记录提取到局部变量中
DELETE FROM my_table
WHERE <whatever conditions>
RETURNING column1, column2, ...
INTO array1, array2, ...
从my_表中删除
哪里
正在返回第1列、第2列。。。
进入阵列1,阵列2。。。
这个方法有点烦人的地方是,您需要将每一列提取到一个单独的变量中。不能在此上下文中使用记录类型。因此,如果您有很多列,它可能会变得很麻烦。Oracle有一种称为高级队列的功能,使用该功能可能比构建自己的队列系统更好 我会对此进行研究,但我们尽量不与oracle绑定得太近。在delete语句之前声明数组(array1、array2)等(对于其他人)会很有用,作为其他人的示例。。。
DELETE FROM my_table
WHERE <whatever conditions>
RETURNING column1, column2, ...
INTO array1, array2, ...