none
SQLによるCJK統合漢字拡張領域文字の抽出 RRS feed

  • 質問

  • お世話になります。
    SQLでの特定文字領域のSELECTについての質問です。

    IMEパッドのUNICODE(追加漢字面)のCJK統合漢字拡張Bに表示される文字が格納されているnvarcharの列があり、

    その中からCJK統合漢字拡張Bの文字のみを抽出したいと考えています。

    外字領域の文字であれば

    like '%[' + nchar(0xE000) + '-' + nchar(0xF8FF) + ']%'

    がありますが、

    例えば上記領域内の「𪛖」という文字は「0xD869 0xDED6」であらわされる為、

    nchar(0xD869)+NCHAR(0xDED6)であらわすことができますが、
    「𪛖」の文字を含んだ列に
    like '%[' + (nchar(0xD869)+NCHAR(0xDED6)) + '-' + (nchar(0xD869)+NCHAR(0xDED6)) + ']%'
    と検索しても検索結果が0件で返ってきます。

    また、SELECT UNICODE(N'𪛖')を実行するとコード値55401が帰り
    SELECT nchar(UNICODE(N'𪛖'))とすると◆に?が入った文字が返ってきます。

    何か方法はございませんでしょうか?


    • 編集済み 7731 2017年12月5日 23:18
    2017年12月5日 22:29

すべての返信

  • SQL Serverのバージョンおよび照合順序の設定に依存します。

    SQL Server 2012以降で照合順序に _SC 付きが選択されているもしくはSQL Server 2014以降の場合、NCHARは0x10000以上の値を受け入れるようになります。なお、0xD869 0xDED6 はUTF-16エンコーディングのサロゲートペアで、これに対応する実際のUCS-2コードポイントは 0x2A6D6 ですので、NCHAR(0x2A6D6) と記述することになります。

    2017年12月5日 23:04
  • 早々のご回答ありがとうございます。

    テスト環境のデータベースの互換性レベルSQLServer2012のため、
    互換性レベルを2014に変更し、
    NCHAR(0x2A6D6) での確認を試してみます。


    • 編集済み 7731 2017年12月5日 23:26
    2017年12月5日 23:26
  • お世話になります。

    互換性レベルを2014に変更し、サービスを再起動し、
    SELECT nchar(0x2A6D6)としてみましたがNULLが帰ってきました。
    like '%[' + nchar(0x2A6D6) + '-' + nchar(0x2A6D6) + ']%'として対象列に検索をかけて見ましたが、
    検索結果は0件でした。

    指定や設定に誤りがあるようでしたらご指摘いただきたく願います。


    2017年12月5日 23:34
  • 照合順序は何を選択されていますでしょうか? 詳しくはリンク先をご確認ください。
    2017年12月6日 2:40
  • お世話になります。

    ありがとうございます。

    互換性を2014に変更すれば、照合順序の設定は不要と解釈してしまいました。

    失礼致しました。

    現状は「Japanese_CI_AS」となります。

    このあと、_SC付きの照合順序に変更してみて検証を行ってみます。


    • 編集済み 7731 2017年12月6日 3:17
    2017年12月6日 3:13
  • お世話になります。

    照合順序を「Japanese_XJIS_100_CI_AS_SC」に変更し、

    SELECT NCHAR(0x2A6D6) を行ってみたところ

    「𪛖」が表示されました。

    ありがとうございます。

    ただし、そのあと、「𪛖」を含む列を作成し、SELECTをしたところ以下の結果となりました。

    TABLE_A

    Col1 Col2
    1 𪛖
    2 𪛖
    3 𪛖𪛖
    4 𪛖
    5 𪛖
    6 (空文字)
    7 (空文字)
    8 あいうえお



    (Col1の型はnvarchar)

    上記に対して以下のSELECT文を発行

    SELECT * FROM TABLE_A
    WHERE Col1 = nchar(0x2A6D6)

    取得結果

    Col1 Col2

    1 𪛖
    2 𪛖
    3 𪛖𪛖
    4 𪛖
    5 𪛖
    6 (空文字)
    7 (空文字)

    期待する結果としてCol1が1,2,4,5の行が対象となってほしいのですが、

    3と6,7が抽出されてしまいます。

    さらにWhere句を

    SELECT * FROM TABLE_A
    WHERE Col1 = ''

    としても上と同じ結果が得られます。

    本事象についておわかりになる方はいらっしゃいますでしょうか。

    2017年12月8日 2:46