我有一条SQL 语句,select * from msg where msg_id in (````````)
括号里的的msg_id有4000条(过长),执行这样的SQL的话,会出错。请问一下,如果我想SQL不变,要怎样才能不出错呢

解决方案 »

  1.   

    使用存贮过程:
    此中使用循环,每次执行300个(最大1000个参数)msg_id。
    返回记录集。
      

  2.   

    --试一下:create or replace procedure p_test(out_var out sys_refcursor)
        as
        begin
        open out_var for select * from msg where msg_id in (````````);
        close out_var;
        open out_var for select * from msg where msg_id in (````````);
        close out_var;
        ......
        end;
        /
      

  3.   


    --这样也不行吗?grant create any procedure to userA;
      

  4.   

    这样试一下:select * from msg where msg_id in ('id1',......) union  
    select * from msg where msg_id in ('id2',......) union
    ......                                                  --每行使用500个msg_id
    ;
      

  5.   

    http://topic.csdn.net/t/20020814/17/940837.htmlHIHI,,我有问题就是类似这样
      

  6.   

    可以考虑建一个中间表(只有1列),里面存储IN中的参数值,然后通过SQL连接进行数据匹配即可.
      

  7.   

    试试使用union,或者换个想法,使用Not in
      

  8.   

    这样的语句适合用exists语句来替换,因为它毕竟有msg_id相匹配的内容
    最重新的是exists比not in和in速度快得多,因为not in和in查询每一笔数据要扫描全表,而exists只扫描与当前条件匹配的内容
      

  9.   

    select * from tab_name a
    (select column_name as fid from table(传一个数组)) b
    where a.fid=b.fid
    这个办法效率高,而且随便你多少长,我们就是这样用的
      

  10.   

    用in第一效率低,第二,如果条件太多,就会出现你所说的问题。最好的办法是用 exists.
      

  11.   


    这个思路是对的,但是一个对象只能传999个参数,也存在限制create or replace type xtype is table of varchar2(200);select * from table(cast xtype('1', '2'/*这里只能有999个,限制了 */) as xtype);
      

  12.   

    基于这个思路,我这里有个测试
    --摘自asktom
    --str2tbl, 将逗号分隔的字符串转成表
    --考虑:写成piple row函数,可优化性能create or replace type str2tblType as table of varchar2(30);
    /create or replace
    function str2tbl( p_str in varchar2, p_delim in varchar2 default ',' )
    return str2tblType
    as
        l_str      long default p_str || p_delim;
        l_n        number;
        l_data     str2tblType := str2tbltype();
    begin
        dbms_application_info.set_client_info( userenv('client_info')+1 );
        loop
            l_n := instr( l_str, p_delim );
            exit when (nvl(l_n,0) = 0);
                    l_data.extend;
                    l_data(l_data.count) := ( ltrim(rtrim(substr(l_str,1,l_n-1))) );
            l_str := substr( l_str, l_n+1 );
        end loop;
        return l_data;
    end;
    /select *
     from TABLE(cast( str2tbl( '1,2,3,4,5' ) as str2tblType) ) t
     
    /
      

  13.   

    现在,楼主只需要写成:select *
      from emp
     where ename in 
    (
    select *
      from table(cast(str2tbl('1,2,3,还有很长长') as str2tblType))
    )--以 scott登录进行的测试, ok.  (不知道楼主的代码,又会不会遇到字符串过长的问题, ^.^)
    select *
      from emp
     where ename in (
    select * from table( cast(str2tbl(rpad('5', 5001, ',5'))  as str2tblType))
    )
      

  14.   

    你们公司的限制还够多的,不能建表,也不能建存储过程,什么破规定啊,呵~~
    见意用exists代替in吧
      

  15.   

    从效率考虑, 这种最好变成NOT IN或是NOT EXISTS