SQL 太 长 问题

liyuncdc 2008-11-19 08:41:12
我有一条SQL 语句,select * from msg where msg_id in (````````)
括号里的的msg_id有4000条(过长),执行这样的SQL的话,会出错。请问一下,如果我想SQL不变,要怎样才能不出错呢
...全文
188 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
DragonBill 2008-11-21
  • 打赏
  • 举报
回复
从效率考虑, 这种最好变成NOT IN或是NOT EXISTS
guangli_zhang 2008-11-21
  • 打赏
  • 举报
回复
居然有这样的SQL,汗
whqcfp 2008-11-20
  • 打赏
  • 举报
回复
用in第一效率低,第二,如果条件太多,就会出现你所说的问题。

最好的办法是用 exists.
microsoft_fly 2008-11-20
  • 打赏
  • 举报
回复
select * from tab_name a
(select column_name as fid from table(传一个数组)) b
where a.fid=b.fid
这个办法效率高,而且随便你多少长,我们就是这样用的
qwx312347236 2008-11-20
  • 打赏
  • 举报
回复
是否可以考虑换一种思路:
in的结果集是怎么等到?如果是从其他表提取出来的数据,则可以把结果集用字查询来代替呢?
多壮志 2008-11-20
  • 打赏
  • 举报
回复
烂设计,死规矩
Andy__Huang 2008-11-20
  • 打赏
  • 举报
回复
这样的语句适合用exists语句来替换,因为它毕竟有msg_id相匹配的内容
最重新的是exists比not in和in速度快得多,因为not in和in查询每一笔数据要扫描全表,而exists只扫描与当前条件匹配的内容


[Quote=引用楼主 liyuncdc 的帖子:]
我有一条SQL 语句,select * from msg where msg_id in (````````)
括号里的的msg_id有4000条(过长),执行这样的SQL的话,会出错。请问一下,如果我想SQL不变,要怎样才能不出错呢
[/Quote]
wangsong145 2008-11-20
  • 打赏
  • 举报
回复
试试使用union,或者换个想法,使用Not in
icss_zhen 2008-11-20
  • 打赏
  • 举报
回复
你们公司的限制还够多的,不能建表,也不能建存储过程,什么破规定啊,呵~~
见意用exists代替in吧
codearts 2008-11-20
  • 打赏
  • 举报
回复
现在,楼主只需要写成:

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))
)
codearts 2008-11-20
  • 打赏
  • 举报
回复
基于这个思路,我这里有个测试


--摘自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

/
codearts 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 microsoft_fly 的回复:]
select * from tab_name a
(select column_name as fid from table(传一个数组)) b
where a.fid=b.fid
这个办法效率高,而且随便你多少长,我们就是这样用的
[/Quote]

这个思路是对的,但是一个对象只能传999个参数,也存在限制

create or replace type xtype is table of varchar2(200);

select * from table(cast xtype('1', '2'/*这里只能有999个,限制了 */) as xtype);
liyuncdc 2008-11-19
  • 打赏
  • 举报
回复
不是数据库上设计的问题,数据库不能随便加表的,这是公司。。
yyy16xx 2008-11-19
  • 打赏
  • 举报
回复
什么设计喔。
把你in的那些条件放到表中是否可以。
mantisXF 2008-11-19
  • 打赏
  • 举报
回复
可以考虑建一个中间表(只有1列),里面存储IN中的参数值,然后通过SQL连接进行数据匹配即可.
[Quote=引用楼主 liyuncdc 的帖子:]
我有一条SQL 语句,select * from msg where msg_id in (````````)
括号里的的msg_id有4000条(过长),执行这样的SQL的话,会出错。请问一下,如果我想SQL不变,要怎样才能不出错呢
[/Quote]
liyuncdc 2008-11-19
  • 打赏
  • 举报
回复
http://topic.csdn.net/t/20020814/17/940837.html

HIHI,,我有问题就是类似这样
liyuncdc 2008-11-19
  • 打赏
  • 举报
回复
好,,谢谢,,我明天试试。。
liyuncdc 2008-11-19
  • 打赏
  • 举报
回复
由于公司数据库的设有访问权限和行权限,所以。。
BlueskyWide 2008-11-19
  • 打赏
  • 举报
回复
这样试一下:

select * from msg where msg_id in ('id1',......) union
select * from msg where msg_id in ('id2',......) union
...... --每行使用500个msg_id
;
BlueskyWide 2008-11-19
  • 打赏
  • 举报
回复

--这样也不行吗?

grant create any procedure to userA;
加载更多回复(3)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧