将修改后的表中的游标用于相同的 PL/SQL 过程

Posted

技术标签:

【中文标题】将修改后的表中的游标用于相同的 PL/SQL 过程【英文标题】:Use cursor from a modified table into the same PL/SQL procedure 【发布时间】:2018-02-12 16:19:50 【问题描述】:

我是 PL/SQL 的新手,我想知道如何解决我的问题。我实际上想将一些值插入到一个表中,然后从这个更新的表中获取值,然后在一个新表中做一些事情。

这是我的示例,我首先将一些值从 TABLE_1 插入到 TABLE_2 中

CREATE or REPLACE PROCEDURE PROC_1 AS
CURSOR C1 IS SELECT DISTINCT COL1 FROM TABLE_1;
BEGIN
   FOR REG IN C1 LOOP
      BEGIN
         INSERT INTO TABLE_2 (COL1) VALUES (REG.COL1);
      END;
   END LOOP;
END;

现在第二次我想检索 TABLE_2 的所有行并循环遍历结果以将一些值插入第三个表 (TABLE_3)

在将值插入 TABLE_2 和更新的 TABLE_2 内容后,如何使用第二个 CURSOR,然后将 TABLE_3 中的值插入同一个 PROC_1 过程?

【问题讨论】:

您不能直接在第一个语句之后添加第二个INSERT 语句吗?顺便说一句,不需要内部的 BEGIN/END 关键字。 您可以使用另一个游标游标 c2 从 table_2 中选择不同的 col1 并对 C2 执行相同的 for 循环并插入到 table_3 中。只是一个想法您还可以使用触发器(但是如果您要插入数百万条记录,这会很慢),您可以将插入到 table_2 中的每一列插入到 table_3 中。 【参考方案1】:

假设您在使用值插入第三个值之前在表格上要做一些事情,您可以使用与第一次插入完全相同的方式:

CREATE or REPLACE PROCEDURE PROC_1 AS
    CURSOR C1 IS SELECT DISTINCT COL1 FROM TABLE_1;
    CURSOR C2 IS SELECT DISTINCT COL1 FROM TABLE_2;
BEGIN
   FOR REG IN C1 LOOP
      BEGIN
         INSERT INTO TABLE_2 (COL1) VALUES (REG.COL1);
      END;
   END LOOP;
   --
   /* ... something ... */
   --
   FOR REG IN C2 LOOP
      BEGIN
         INSERT INTO TABLE_3 (COL1) VALUES (REG.COL1);
      END;
   END LOOP;
END;

例如:

SQL> select count(1) from table_1;

  COUNT(1)
----------
         2

SQL> select count(1) from table_2;

  COUNT(1)
----------
         0

SQL> select count(1) from table_3;

  COUNT(1)
----------
         0

SQL> exec proc_1;

PL/SQL procedure successfully completed.

SQL> select count(1) from table_2;

  COUNT(1)
----------
         2

SQL> select count(1) from table_3;

  COUNT(1)
----------
         2

SQL>

但是,您不需要游标,您可以编写如下过程:

CREATE or REPLACE PROCEDURE PROC_2 AS
BEGIN
   INSERT INTO TABLE_2 (COL1) SELECT COL1 FROM TABLE_1;
   --
   /* ... something ... */
   --
   INSERT INTO TABLE_3 (COL1) SELECT COL1 FROM TABLE_2;
END;

给出:

SQL> DELETE TABLE_2;

2 rows deleted.

SQL> DELETE TABLE_3;

2 rows deleted.

SQL> EXEC PROC_2;

PL/SQL procedure successfully completed.

SQL> select count(1) from table_2;

  COUNT(1)
----------
         2

SQL> select count(1) from table_3;

  COUNT(1)
----------
         2

【讨论】:

【参考方案2】:

您可以为此使用全局临时表。

CREATE GLOBAL TEMPORARY TABLE my_temp_table (
  id           NUMBER,
  description  VARCHAR2(20)
)
ON COMMIT PRESERVE ROWS;

https://oracle-base.com/articles/misc/temporary-tables

【讨论】:

以上是关于将修改后的表中的游标用于相同的 PL/SQL 过程的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列

Oracle 修改 sys refcursor 并在 PL/SQL 中返回修改后的游标

PL/SQL 仅使用游标将 2 个表中的数据检索到新表中

如何传递从多个表创建的 PL/SQL 游标记录?

将新列添加到现有表中并使用 PL/SQL 中游标中的值更新它们

如何将游标添加到 PL/SQL 块中的过程中?