将修改后的表中的游标用于相同的 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 中返回修改后的游标