我遇到“IN”子句的最大表达式数量问题。基本上我原来是..
WHERE X IN (1, 2, 3...1001);
但是这会导致错误,因为在IN子句中只能有1000个表达式。所以我决定把它换成一张桌子。我正在传递表达式的CSV值(例如“1,2,3 ......”),我可以使用它将其拆分并插入临时表中。
然而,这个改变导致我有一个新问题,regexp_substr函数作为你可以传递的字符串长度的限制(我相信512字节)。以下是我如何做这个的示例代码...
SELECT * FROM dual
WHERE X IN (SELECT regexp_substr('1, 2,..., 1001', '[^,]+', 1, level)
FROM dual
CONNECT BY regexp_substr('1, 2,..., 1001', '[^,]+', 1, level) IS NOT NULL)
我觉得我可能正试图将方形钉子钉入圆形孔中。有没有更好的方法来处理这个过长的字符串?我正在考虑使用JavaScript将字符串拆分为更易于管理的部分,并一次传递一个。
答案 0 :(得分:1)
有两种明显的选择。
我猜你看过Git documentation on git clean。 第一种选择是来自该页面的评论:
而不是
where t.X in (1, 2, 3, ..., 1001)
你可以使用
where instr ('|1|2|3|...|1001|', '|' || t.X || '|') > 0
注意前导和尾随'|'两个论点。
但请注意,这种简单的方法无法从
中受益create index t_x on t(X).
因此,除非你有其他好的限制,否则你将以全表扫描结束。
第二种方法是创建一个函数split_func,其签名更像是
function split_func
( pi_csv in varchar2
, pi_separator in varchar2 default ','
, pi_trim in varchar2 default 'Y'
-- Y/N, because boolean is not allowed for functions in SQL
)
return SYS.ODCIVarchar2List PIPELINED;
-- SYS.ODCIVarchar2List is a varray of varchar2(4000)
我会将实际编码留给读者练习。
然后你可以像这样使用那个函数(假设你的列X是一个数字):
with search_values as
(
select to_number(column_value) as n
from table (split_func ('1,2,3,...,1001'))
)
select t.*
from t, search_values
where t.X = search_values.n;
如果您的列t在X上有索引,则此查询可以使用它。
在clob中使用pi_csv的重载函数也是有意义的。