【この記事を読むのに必要な時間は約 5 分です】
検索画面を作成する場合、対象データの絞込みにはユーザーの利便性を考慮して部分一致を採用することが一般的です。同じキーワードを含むデータが大量に存在するなど、部分一致では絞り込みが難しい場合はデータの特性にあわせ前方一致・後方一致を採用します。
このようなあいまい検索 (Like 検索) に加え、全角・半角や大文字・小文字、ひらがな・カナを区別しない絞込みを行うことでさらに利便性を上げられるケースもあります。例えば検索対象が企業名や商品名の場合は趣向を凝らした名称が用いられているため、ユーザーはうろ覚えの名称で検索を行いたい場合があります。
例えば ‘abc’ と入力したとき ‘ABCマート’ が、’ソフト’ と入力したときには ‘そふとうぇあ開発株式会社’ と ‘ソフトウェア工房’ を検索結果に表示させる検索の実装方法を考えてみましょう。
比較対照が英数字に限られるケース
検索対象文字列が英数字に限られる場合は UPPER / LOWER、TO_MULTI_BYTE / TO_SINGLE_BYTE を使用して文字形式を変換、統一後に比較することで容易に実装できます。下記のサイトにあるように、NLSSORT 関数を使用するのも有効です。
全角・半角、大文字・小文字を区別しない検索 – SHIFT the Oracle
比較対照に英数字・かな・カタカナが混在するケース
次に、英数字やかな、カナが混在するケース を考えます。大文字、小文字、半角、全角を同値とする NLSSORT 関数 (JAPANESE_M_CI) がそのまま使えそうに思えます。ですが、この関数では全角カナと半角カナの差異が完全に解決されず、like 検索できないという致命的な問題があります。
回避策として ‘ア’ → ‘ア’ 、’イ’→’イ’ のように文字を一文字ずつ判定して変換する関数を作成する、という涙ぐましい実装が行われているのを見たことがありますが、10gR2 からは UTL_I18N.TRANSLITERATE という日本語のひらがなとカタカナの変換を行う機能が提供されています。
以下の SQL は、英数字対応として UPPER / TO_SINGLE_BYTE 関数を、かな / カナ対応として TRANSLITERATE 関数を使用して、比較元と比較対照の文字列の型が合うように変換している例です。
select corporation_name from 会社マスタ where UTL_I18N.TRANSLITERATE(UPPER(TO_SINGLE_BYTE(corporation_name)),'kana_fwkatakana') like '%' || UTL_I18N.TRANSLITERATE(UPPER(TO_SINGLE_BYTE( /*検索文字*/ )),'kana_fwkatakana') || '%'
ただし、促音や濁音、半濁音も区別せず同一で検索したい(「っ」→「つ」、「だ」→「た」)という要望があればこの方法では対応できませんので、清音に変換する独自のファンクションを作成して対応することになるでしょう。
また Where 句に関数を使用すると検索対象のレコード数と同じ回数関数が実行されるため、パフォーマンスの低下が発生する場合があります。対象テーブルのレコード件数が膨大な場合、レコード登録時に検索用の変換済み文字列を併せて格納するカラムを設けることを検討すべきです。
UTL_I18N パッケージ
UTL_I18N パッケージに含まれる TRANSLITERATEファンクションでは、日本語のひらがなとカタカナの変換機能が提供されています。
上記の例のように第 2 引数に以下のいずれかの定数を指定すると、変換後の文字列が返されます。
‘fwkatakana_hiragana’ – 全角カタカナのみを全角ひらがなに変換します。
‘fwkatakana_hwkatakana’ – 全角カタカナのみを半角カタカナに変換します。
‘hiragana_fwkatakana’ – 全角ひらがなのみを全角カタカナに変換します。
‘hiragana_hwkatakana’ – 全角ひらがなのみを半角カタカナに変換します。
‘hwkatakana_fwkatakana’ – 半角カタカナのみを全角カタカナに変換します。
‘hwkatakana_hiragana’ – 半角カタカナのみを全角ひらがなに変換します。
‘kana_fwkatakana’ – すべてのタイプの仮名文字を全角カタカナに変換します。
‘kana_hiragana’ – すべてのタイプの仮名文字を全角ひらがなに変換します。
‘kana_hwkatakana’ – すべてのタイプの仮名文字を半角カタカナに変換します。