使用 FORALL 和 RETURNING 插入表时如何获取 ROWID
Posted
技术标签:
【中文标题】使用 FORALL 和 RETURNING 插入表时如何获取 ROWID【英文标题】:How to get ROWID when inserting into table using FORALL and RETURNING 【发布时间】:2017-09-12 07:43:59 【问题描述】:我想使用 FORALL INSERT 语句(批量插入)中的 RETURNING 子句将插入记录的 ROWID 返回到 pl/sql 记录表(关联记录数组)中。 我相信,这个问题在于同时使用 FORALL 和 BULK COLLECT 中的记录表。
看例子:
CREATE TABLE test2 (num NUMBER);
set serveroutput on
DECLARE
TYPE r_rec IS RECORD (num NUMBER, row_id ROWID);
-- TYPE t_rid IS TABLE OF rowid INDEX BY BINARY_INTEGER;
TYPE t_tab IS TABLE OF r_rec INDEX BY BINARY_INTEGER;
v_tab t_tab;
--v_rid t_rid;
BEGIN
v_tab(1).num := 1.11;
v_tab(2).num := 2.22;
v_tab(3).num := 3.33;
--
FORALL i IN v_tab.first..v_tab.last
INSERT INTO test2 (num)
VALUES (v_tab(i).num)
RETURNING rowid BULK COLLECT INTO v_tab(i).row_id
;
FOR i IN v_tab.first..v_tab.last
LOOP
dbms_output.put_line('num/rowid : ' || v_tab(i).num || '/' || v_tab(i).row_id);
END LOOP;
END;
/
引发错误:PLS-00437: FORALL bulk index cannot be used in RETURNING clause 这里哪里有问题?我是否需要另一个 PL/SQL 表来返回 ROWID?
【问题讨论】:
好吧,rowid 是在插入记录时分配给该记录的。可以在 RETURNING 子句中获取它。我只需要将它放回 pl/sql 表+记录中。请参阅示例。我的问题与此有关。 【参考方案1】:我是否需要另一个 PL/SQL 表来返回 ROWID?
是的 ..您可以尝试如下:您需要另一个集合来保存 rowids 的返回,因为“FORALL 批量索引不能用于 RETURNING 子句”
DECLARE
TYPE r_rec IS RECORD (num NUMBER, row_id ROWID);
TYPE t_tab IS TABLE OF r_rec INDEX BY BINARY_INTEGER;
v_tab t_tab;
TYPE r_rw IS TABLE OF ROWID index by pls_integer;
v_rw r_rw;
BEGIN
v_tab(1).num := 1.11;
v_tab(2).num := 2.22;
v_tab(3).num := 3.33;
--
FORALL i IN v_tab.first..v_tab.last
INSERT INTO test2 (num)
VALUES (v_tab(i).num)
RETURNING rowid BULK COLLECT INTO v_rw;
FOR i IN v_tab.first..v_tab.last
LOOP
dbms_output.put_line('num/rowid : ' || v_tab(i).num || '/' ||v_rw(i));
END LOOP;
END;
/
【讨论】:
不幸的是,这是一个有点脆弱的解决方案,因为不能确保v_rw
的索引与v_tab
的索引相同。但这似乎是唯一可能的解决方案。
@LiborStefek。这是在v_tab
的循环中运行的,因此您可以确定使用的索引是正确的。请参阅此dba-oracle.com/plsql/t_plsql_dml.htm。此外,如果这回答了您的查询,您可以通过接受解决方案来关闭问题。
尝试将v_tab(1).num := 1.11;
更改为v_tab(4).num := 1.11;
。 i
的索引是 2,3,4,但 v_rw
的索引是 1,2,3。这就是我所说的“脆弱”。我需要考虑到这一点。
那么v_tab(1).num
的值是多少?你想制作稀疏集合还是什么?然后它会抛出错误。
Indices i are 2,3,4,
- 没有 Oracle 认为 FORALL i
索引不是您的集合索引。另外,当你做这样的事情时,它会抛出错误。试试看。以上是关于使用 FORALL 和 RETURNING 插入表时如何获取 ROWID的主要内容,如果未能解决你的问题,请参考以下文章
我试图从 sys_refcursor 获取 bulkcollect 记录并尝试使用 forall 插入另一个表,但它抛出了一条错误消息
Oracle pl/sql forall:如何计算表空间已满(1654)错误的实际插入行数
如何在 APEX 应用程序的 csv 文件的批量数据插入中使用 forall 语句