• Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题


    在实际PL/SQL编程中,我们要对动态取出来的一组数据,进行For循环处理,其基本程序逻辑为:

    create or replace procedure getidlist
    is
      l_idlist varchar2(200);
    begin
      l_idlist:='1,2,3,4';
      for brrs in (select * from bldroom where bldroomid in (l_idlist))
      loop
          brrs.structure:='钢混';
      end loop;
    end;
    /
    show err;
    

    1、编译该程序,可以正常通过;

    2、执行该程序exec getidlist,系统提示:ORA-01722: invalid number,ORA-06512: at "TT.GETIDLIST", line 6

    解决方案:

    CREATE OR REPLACE TYPE type_split IS TABLE OF VARCHAR2 (4000);
    create or replace function split(p_list varchar2,p_sep varchar2 := ',') return type_split pipelined
    IS 
     l_idx pls_integer; 
     v_list varchar2(50) := p_list; 
     begin 
          loop 
               l_idx := instr(v_list,p_sep); 
               if l_idx > 0 then 
                   pipe row(substr(v_list,1,l_idx-1)); 
                   v_list := substr(v_list,l_idx+length(p_sep)); 
               else 
                    pipe row(v_list); 
                    exit; 
               end if; 
          end loop; 
          return; 
     end split;
    

    此时修改getidlist代码如下:

    create or replace procedure getidlist
    is
      l_idlist varchar2(200);
    begin
      l_idlist:='1,2,3,4';
      for brrs in (select * from bldroom where bldroomid in (select column_value from table(split(l_idlist,','))))
      loop
          brrs.structure:='钢混';
      end loop;
    end;
    /
    show err;
    

    执行:exec getidlist;

    提示错误:ORA-22905: cannot access rows from a non-nested table item


    再次修改getidlist代码如下:

    create or replace procedure getidlist
    is
      brRow    bldroom%rowtype;
      l_idlist varchar2(200);
    begin
      l_idlist:='1,2,3,4';
      for idrs in (select column_value from table(split(l_idlist,',')))
      loop
          select * into brRow from bldroom where bldroomid=idrs.column_value;
          brRow.structure:='ssss';
      end loop;
    end;
    /
    show err;
    

    OK,搞定。

    附:PL/SQL表---table()函数用法

    摘录

    /*
    利用table()函数,我们可以将PL/SQL返回的结果集代替table。
    oracle内存表在查询和报表的时候用的比较多,它的速度相对物理表要快几十倍。
    */
    /*
    simple example:
    1、table()结合数组:
    */
    
    create or replace type t_test as object(
    id integer,
    rq date,
    mc varchar2(60)
    );
    
    create or replace type t_test_table as table of t_test;
    
    create or replace function f_test_array(n in number default null) return t_test_table
    as 
    v_test t_test_table := t_test_table();
    begin
    for i in 1 .. nvl(n,100) loop
    v_test.extend();
    v_test(v_test.count) := t_test(i,sysdate,'mc'||i);
    end loop;
    return v_test;
    end f_test_array;
    /
    
    select * from table(f_test_array(10));
    
    select * from the(select f_test_array(10) from dual);
    
    /*
    2、table()结合PIPELINED函数:
    */
    
    create or replace function f_test_pipe(n in number default null) return t_test_table PIPELINED 
    as 
    v_test t_test_table := t_test_table();
    begin 
    for i in 1 .. nvl(n,100) loop
    pipe row(t_test(i,sysdate,'mc'||i)); 
    end loop; 
    return; 
    end f_test_pipe; 
    /
    
    select * from table(f_test_pipe(20));
    
    select * from the(select f_test_pipe(20) from dual);
    
    /*
    3、table()结合系统包:
    */
    
    create table test (id varchar2(20));
    insert into test values('1');
    commit;
    explain plan for select * from test;
    select * from table(dbms_xplan.display);
    
     
    

    关于错误:ORA-22905: cannot access rows from a non-nested table item 的解决方案,不知各位大侠有没有更好的解决方案?请指教。

  • 相关阅读:
    计算两个时间相差几个月
    批量生成二维码
    PHP实现二维数组(或多维数组)转换成一维数组
    任意二维数组转换成一维数组
    企业微信的使用与公众号以及其它几个应用的使用方式都是一致的
    判断字符类型
    insert一个表的数据到另外一个表
    同步a表的数据到 b表
    PHP Curl Accept-Encoding: gzip乱码问题解决
    spring boot入门程序
  • 原文地址:https://www.cnblogs.com/advocate/p/1805810.html
Copyright © 2020-2023  润新知