regexp_substr字符串长度

时间:2016-07-13 20:18:09

标签: oracle10g birt

我遇到“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将字符串拆分为更易于管理的部分,并一次传递一个。

1 个答案:

答案 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的重载函数也是有意义的。