BULK收集到LOOP内的对象表?

时间:2017-08-18 11:51:55

标签: sql oracle plsql

这就是我现在所做的事情。我创建了这个对象和对象表。

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

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

1 个答案:

答案 0 :(得分:1)

对于特定问题的答案是这样的,因为循环中的select始终只返回一行:

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的信息,很难确定!