[Oracle] CONTAINS 演算子を使用した際によく発生するエラー | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

以下のように CONTAINS 演算子を使用して全文検索を実行する際、検索キーワードにセットする文字列によって様々なエラーが発生します。

SELECT NAME, SCORE(1)
	FROM DOCUMENT_TEXT
	WHERE CONTAINS( TEXT, :value, 1 ) > 0;

中でもよく起こりがちなエラーを以下に挙げてみます。


256byte を超える検索キーワードを指定した場合
検索キーワードに 256byte を超える文字列をセットした場合、以下のエラーが発生します。

行1でエラーが発生しました。:
ORA-29902: ODCIIndexStart()ルーチンの実行中にエラーが発生しました。
ORA-20000: Oracle Text error:
DRG-50943: 行1(列2)で、問合せトークンが長すぎます
これは1つの検索キーワードに指定できる文字列の最大長が 256byte までとなっているためです。

このエラーは事前に検索キーワードの長さをチェックするなどすれば回避できます。

ただ、制限の単位が byte ということは、文字コード、文字種によって入力可能文字数が変化するわけで、エンドユーザーにその仕様をどう説明するかが悩ましいケースもありそうです。

(実際、256byte 以上の検索キーワードを入力することはほとんどないでしょうが...)


空文字列をセットした場合
検索キーワードに空文字列をセットした場合、以下のエラーが発生します。

行1でエラーが発生しました。:
ORA-29902: ODCIIndexStart()ルーチンの実行中にエラーが発生しました。
ORA-20000: Oracle Text error:
DRG-50901: 行1(列1)にテキスト問合せの解析構文エラーが発生しました
これはエラーにしないでほしいところですが、エラーになってしまいます。

このエラーは事前に検索キーワードが空文字列かどうかをチェックするなどすれば回避できます。
あるいは検索結果 0件で返したい場合は、無理矢理半角スペースなどで検索するという手もあります。


エスケープ文字で終わる場合
検索キーワードの最後の文字が '\' だった場合、または検索キーワードに '}' と対になっていない '{' が含まれている場合、以下のエラーが発生します。

行1でエラーが発生しました。:
ORA-29902: ODCIIndexStart()ルーチンの実行中にエラーが発生しました。
ORA-20000: Oracle Text error:
DRG-50900: 行1(列7)にテキスト問合せの解析エラーが発生しました
DRG-50917: テキスト問合せ文字列の終わりでエスケープします

また、'{' と対になっていない '}' が含まれている場合、以下のエラーが発生します。

行1でエラーが発生しました。:
ORA-29902: ODCIIndexStart()ルーチンの実行中にエラーが発生しました。
ORA-20000: Oracle Text error:
DRG-50901: 行1(列2)にテキスト問合せの解析構文エラーが発生しました
'\'、'{'、'}' はエスケープ文字になります。これらの文字がエスケープ文字として正しい使われ方をしていない場合、Oracle は正常に解釈することができません。

このエラーは事前に検索キーワードに '\'、'{'、'}' が含まれていないかどうかをチェックし、含まれている場合は '\\'、'{{'、'}}' というようにエスケープしてやることによって回避できます。

特殊な演算子を駆使したような全文検索の場合は、他にもいろいろ考慮すべき点があるかもしれませんが、単純な全文検索の場合は、おそらく上記の 3つのエラーへの対策を施しておけば問題ないのではないでしょうか。