zoukankan      html  css  js  c++  java
  • Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题

    转:

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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

    解决方案:

    1
    CREATE OR REPLACE TYPE type_split IS TABLE OF VARCHAR2 (4000);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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()函数用法

    摘录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    /*
    利用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 的解决方案,不知各位大侠有没有更好的解决方案?请指教。

  • 相关阅读:
    [转] 《大腕》——编程高手篇
    [转] 如何用VB.Net创建一个三层的数据库应用程序
    [转] 张孝祥的java试题
    [转] 很久以前的一个sql面试题及答案.
    [转] C#编程实践
    [转] html技巧
    [转] 揭开SVCHOST.exe进程之谜
    [转] c#.net常用函数和方法集
    [转] Visual Studio.Net 快捷键表
    [转] left join/right join/inner join操作演示
  • 原文地址:https://www.cnblogs.com/libin6505/p/11971410.html
Copyright © 2011-2022 走看看