Oracle &引用;散装收集到;及;立即执行;在甲骨文中

Oracle &引用;散装收集到;及;立即执行;在甲骨文中,oracle,Oracle,是否可以在oracle中使用“立即执行”命令执行“批量收集到”?所有这些都是返回管道表格的函数的一部分。是的,从技术上讲,您可以: 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_o

是否可以在oracle中使用
“立即执行”
命令执行
“批量收集到”
?所有这些都是返回管道表格的函数的一部分。

是的,从技术上讲,您可以:

  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 
Oracle在文档中明确说明了这一点:

但如果您真的需要执行动态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   

按照Dmitry Nikiforov提出的想法,我使用游标解决了这个问题,下面是解决方案;)


我真的需要使用动态sql,所以您认为使用refcursors比取消批量收集更好吗?是的,如果要处理大量行,refcursor是一个相关的解决方案。LIMIT允许您一步一步地获取部分记录,而不是一次抽取PGA中的所有卷。这是一个古老的问题,但很流行,在Oracle 18中仍然有效。我想指出,@DmitryNikiforov说的是更有用的方法,因为您不希望在代码中立即执行“..”批量收集到xx,除非您确信记录的数量总是合理的小。否则,它将一直工作到有一天记录量过大为止。
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;