【问题标题】:BULK COLLECT into table of objects inside LOOP?BULK COLLECT 到 LOOP 内的对象表中?
【发布时间】:2018-01-27 02:27:08
【问题描述】:

这是我到目前为止所做的。我创建了这个对象和对象表。

CREATE TYPE my_obj as object(
   val1      varchar2(30),
   val2     varchar2(30),
   val3      varchar2(30));

create TYPE table_obj IS TABLE OF my_obj;

在我的程序中,我这样做:

PROCEDURE MYPROC(
    TABLEOBJ                          OUT     table_obj, 
    MYCURSOR                          OUT     OTHERPCK.REFCURSOR,
    ...other IN param)
AS

--other code

在 LOOP 中,我需要进行查询,它会在每次迭代时提供三个 varchar2 值作为输出(即 val1、val2、val3),我需要将它们存储在 TABLEOBJ 中,并在查询此表后放入所有结果在我的参考光标上,所以:

 BEGIN    
 FOR SOMETHING IN SOMETHINGELSE LOOP

 SELECT my_obj(VAL1, VAL2, VAL3) BULK COLLECT INTO TABLEOBJ
 FROM ...
 WHERE ...
 ENDLOOP;

 OPEN MYCURSOR FOR SELECT * FROM TABLE(TABLEOBJ);

代码编译没有问题,但我在 MYCURSOR 中只得到一行,而且肯定不止一行。我也试过:

SELECT VAL1, VAL2, VAL3 INTO TABLEOBJ

但我明白了:

PL/SQL: ORA-00947: not enough values

如何将选择的每个结果(总是这三个 varchar2 中的一行)并保存到 TABLEOBJ?

【问题讨论】:

  • 为什么要使用循环?如果您在循环中的选择每次只返回 1 行,那么您将继续覆盖集合并最终只返回 1 行。 bulk collect 的重点是一次性选择所有您需要的行(或者如果一次性获取的行太多,则至少选择一批)。
  • 因为我的 WHERE 条件不同,并且基于显式引用光标“SOMETHINGELSE”内的“SOMETHING”列。你知道不使用批量收集来完成这项任务的方法吗?
  • 您仍然应该尝试将 somethingelse 查询与您在循环内执行的任何查询结合起来,这样您就可以得到一个包含所有相关数据的结果集 - 然后您 @ 987654328@ 加入您的收藏。如果不了解这些查询实际上是什么,很难更具体。

标签: sql oracle plsql


【解决方案1】:

您的具体问题的答案是这样的,因为循环内的选择始终只返回一行:

DECLARE
  obj my_obj;
  tableobj table_obj := table_obj(); -- Initialise the collection
BEGIN    
 FOR SOMETHING IN SOMETHINGELSE LOOP

 SELECT my_obj(VAL1, VAL2, VAL3) INTO obj
 FROM ...
 WHERE ...

   tableobj.extend();
   tableobj(tableobj.COUNT) := obj;
 ENDLOOP;

 OPEN MYCURSOR FOR SELECT * FROM TABLE(TABLEOBJ);

但是,我确信可以重写您的查询以完全避免循环:

BEGIN    

 SELECT my_obj(VAL1, VAL2, VAL3) BULK COLLECT INTO TABLEOBJ
 FROM ...
 WHERE ... IN (SELECT SOMETHING ... SOMETHINGELSE)

 OPEN MYCURSOR FOR SELECT * FROM TABLE(TABLEOBJ);

但如果不了解更多关于 SOMETHING 和 SOMETHINGELSE 的信息,就很难确定!

【讨论】:

  • 感谢您的回答!我正在尝试第一种方法,但我在 tableobj.extend() 上收到此错误“ORA-06531: Reference to uninitialized collection”;你知道这是怎么回事吗?
  • 你需要初始化tableobj - 我会更新我的答案。
  • 谢谢,等不及了!在等待期间,我会尝试遵循您的第二条建议。
  • 有效!非常感谢您的支持。对于未来的读者:显然,如果有这样的局部变量,则不需要为该表类型提供 OUT 参数:“tableobj table_obj := table_obj();”
猜你喜欢
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多