2014-01-14 94 views

回答

8

是的,理论上你可以:

1 SQL> declare 
    2 type x is table of t.id%type index by pls_integer; 
    3 xx x; 
    4 begin 
    5 execute immediate 
    6 'select id from t' bulk collect into xx; 
    7 dbms_output.put_line(xx.count); 
    8 end; 
    9/
426 

而且甲骨文明确规定此文档中:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/executeimmediate_statement.htm

但如果你真的需要执行动态,你可以用更有效的方法事件SQL - 弱引用游标。您将可以访问LIMIT等强大的选项,并且可以使用记录集合。

SQL> declare 
    2 type x is table of t%rowtype index by pls_integer; 
    3 xx x; 
    4 c sys_refcursor; 
    5 begin 
    6 open c for 'select * from t'; 
    7 loop 
    8  fetch c bulk collect into xx limit 100; 
    9  dbms_output.put_line(xx.count); 
10  exit when c%notfound; 
11 end loop; 
12 close c; 
13 end; 
14/
100                    
100                    
100                    
100                    
26 
+0

我真的需要使用动态SQL,所以你想使用refcursors是一个更好的主意比取消批量收集? –

+0

是的,如果您要进行大批量的行,则ref cursor是相关的解决方案。 LIMIT允许您逐步获取记录的一部分,而不是一次性抽取PGA中的所有音量。 –

1

继梅德尼基福罗夫提出的想法,我使用游标解决了这个问题,在这里是解决方案;)

FUNCTION myFunction ( parameter_p IN VARCHAR2) RETURN myTableType PIPELINED 

IS 
    c sys_refcursor; 
    stmt varchar2(4000); 
    out_rec mYrowType; 
    rec mYrowType; 
BEGIN 

    stmt:='Select * from ''' || parameter_p || ''''; 
    open c for stmt; 

    LOOP 
    fetch c into rec; 
    EXIT WHEN c%NOTFOUND; 

     out_rec.field1 := rec.field1; 
     out_rec.field2 := rec.field2; 
     out_rec.field3 := rec.field3; 

     PIPE Row(out_rec); 
    END LOOP; 

    Close c; 
    Return; 

END myFunction;