Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle-在过程中选择并删除_Oracle_Plsql - Fatal编程技术网

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

我需要从Oracle过程返回一个行集,然后在同一过程中删除它们。没有临时表,有没有一种简洁的方法?可能是内存中的光标


基本上,我是从队列中弹出记录,我希望避免两次往返,因为这是一个非常频繁的过程。

您可以使用光标进行更新,例如

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, ...