Sql 批量收集到多个集合中
我想知道在多个集合中使用Sql 批量收集到多个集合中,sql,oracle,plsql,cursor,oracle12c,Sql,Oracle,Plsql,Cursor,Oracle12c,我想知道在多个集合中使用大容量收集是否可以保证行中的相应列在嵌套表中具有相同的索引 例如: CREATE TABLE tx AS SELECT CAST(level AS INT) AS col1, level || 'a' AS col2, level || 'b' as col3 FROM dual CONNECT BY level <= 100000; 和代码: DECLARE CURSOR cur IS SELECT /*+parallel(4)*/col1, col2,
大容量收集是否可以保证行中的相应列在嵌套表中具有相同的索引
例如:
CREATE TABLE tx AS
SELECT CAST(level AS INT) AS col1, level || 'a' AS col2, level || 'b' as col3
FROM dual
CONNECT BY level <= 100000;
和代码:
DECLARE
CURSOR cur IS SELECT /*+parallel(4)*/col1, col2, col3 FROM tx;
TYPE t1 IS TABLE of INT;
TYPE t2 IS TABLE of VARCHAR2(20);
vt1 t1;
vt2 t2;
vt3 t2;
BEGIN
OPEN cur;
FETCH cur BULK COLLECT INTO vt1, vt2, vt3 LIMIT 1000;
LOOP
FOR i IN 1..vt1.COUNT LOOP
DBMS_OUTPUT.put_line('i => '|| i || ' vt1 => ' || vt1(i)
|| ' vt2 => '|| vt2(i) || ' vt3 =>' || vt3(i));
END LOOP;
EXIT WHEN cur%NOTFOUND;
FETCH cur BULK COLLECT INTO vt1, vt2, vt3 LIMIT 1000;
END LOOP;
CLOSE cur;
END;
输出:
i => 1 vt1 => 22418 vt2 => 22418a vt3 =>22418b
i => 2 vt1 => 22419 vt2 => 22419a vt3 =>22419b
i => 3 vt1 => 22420 vt2 => 22420a vt3 =>22420b
i => 4 vt1 => 22421 vt2 => 22421a vt3 =>22421b
i => 5 vt1 => 22422 vt2 => 22422a vt3 =>22422b
i => 6 vt1 => 22423 vt2 => 22423a vt3 =>22423b
所以每一行都有相同的前缀。或者在某些情况下,可能会得到如下结果:
i => 1 vt1=> 100 vt2=>200a vt3=>300b
备注:我知道我可以定义记录类型并只使用一个集合
正在寻找来自官方来源的答案。很抱歉,我没有来自官方来源的任何信息,但我猜取消同步是不可能的,因为这意味着如果您使用记录类型,您的集合中可能会出现损坏的记录
例如:rec.vt1=>100 rec.vt2=>200a rec.vt3=>300a
这基本上意味着批量收集不可靠。Oracle的PL/SQL语言参考文档没有明确说明同一行中的值将具有相同的索引,但它确实说明:
PL/SQL处理BULK COLLECT子句的方式与它在循环语句中处理FETCH语句的方式类似
另外,BULK COLLECT
一章给出了隐式假设来自同一行的值将具有相同索引的示例。例如,这来自12.1版Oracle PL/SQL语言参考中的示例12-22
请参阅:除了Matthew McPeak的发现,我认为这里的关键实际上是,它总是从表中选择整行:
FETCH语句从数据库的结果集中检索数据行
多行查询一次查询一行、一次查询多行或全部
行,并将数据存储在变量、记录或
收藏
因此,在获取行之后,Oracle可以将它们放入一个记录或一个或多个集合(如您的示例),但无论哪种方式,索引都是一致的(从同一行提取)。doc中的好示例。谢谢。此外,Oracle支持说明1066713.1(如果您有访问权限)显示了具有和不具有批量收集
的等效块的示例。您可以看到,等效的无批量收集块对所有收集使用单个计数器,而不是每个收集使用一个计数器。
i => 1 vt1=> 100 vt2=>200a vt3=>300b
FOR i IN names.FIRST .. names.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(' Employee ' || names(i) || ': $' || sals(i));
END LOOP;