2016-07-13 13 views
0

"IN"節の式の最大数に問題があります。基本的に私はもともと..regexp_substr文字列長さ

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つずつ渡すことを検討しています。

答えて

1

2つの明白な選択肢があります。

私はあなたがhttps://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statementを読むと思います。 最初の選択肢は、そのページ上のコメントからである:

代わりの

where t.X in (1, 2, 3, ..., 1001) 

あなたは先頭と末尾の

where instr ('|1|2|3|...|1001|', '|' || t.X || '|') > 0 

注意を使用することができます '|'どちらの議論でも。

は、あなたが他の良い制限がある場合を除き、あなたは全表スキャンで終わるだろう、この単純なアプローチは、このように

create index t_x on t(X). 

の恩恵を受けることができないこと、しかし、注意してください。

第二のアプローチは、私は、読者の演習として実際の符号化を任せ以下この

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) 

ような署名より鉱石と機能split_funcを作成することです。

次に、あなたは(あなたの列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上のインデックスを持っている場合は、このクエリはそれを使用することができます。

Btwは、clobのpi_csvでオーバーロードされた関数も意味をなさないでしょう。