zoukankan      html  css  js  c++  java
  • 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 的解决方案,不知各位大侠有没有更好的解决方案?请指教。

  • 相关阅读:
    Android见招拆招五:XML匹配问题、XML资源引用的必要性
    Android见招拆招四:Manifest.xml内容神秘还原
    Android学习笔记三:Intent实现页面跳转
    Android学习笔记二:(布局)Linear Layout、Layout weight测试
    Android见招拆招三:Eclipse软件误报
    Android学习笔记一:(布局)fill_parent、wrap_content、match_parent实例测试
    文件读写(笔记)
    常用的异常
    面向过程、函数式、面向对象
    time&datetime&random模块
  • 原文地址:https://www.cnblogs.com/advocate/p/1805810.html
Copyright © 2011-2022 走看看