SQL Server 2012 では、補助文字の照合順序 (SC:Supplementary Characters) が追加されました。
この照合順序を使うと何ができるようになるのかを見てみたいと思います。
■SC を使うとできるようになること。
SQL Server 2005 で導入された [Japanese_90] や SQL Server 2008 で導入された [Japanese_XJIS_100] は JIS2004 に対応した照合順序というのは聞くことがあるかと思います。
その 4:JIS X 0213:2004 (JIS2004) をサポートする。~ 消えた大口顧客 ~
SQL Server における JIS2004 対応について寄せられる質問と回答
これらの照合順序を使用するとサロゲートペアの文字列の比較やソートが実施できていたのですが [SC の照合順序なし] に書かれているような制限がありました。
これらの対応がされたものが SQL Server 2012 で追加された SC という照合順序になります。
上から順に 1 ~ 5 としてそれぞれどのように変わったのかを見てみたいと思います。
今回は以下のクエリで作成したテーブル / データを使用しています。
SQL Server は列単位に照合順序を変えることができますので、Col1 に SQL Server 2008 R2 までの照合順序を、Col2 に SQL Server 2012 で追加された照合順序を設定しています。
CREATE TABLE dbo.TblTest ( Col1 nvarchar(50) COLLATE Japanese_XJIS_100_CI_AS NULL, Col2 nvarchar(50) COLLATE Japanese_XJIS_100_CI_AS_SC NULL ) GO INSERT INTO TblTest VALUES(N’森?外??る’, N’森?外??る’) INSERT INTO TblTest VALUES(N’森鴎外叱る’, N’森鴎外叱る’) |
この手のテストを実施するときに [森?外??る] という文字を使うことがあります。
文字の説明の詳細については、Tech Fielders コラムの [Windows 7 : 製品ソフト開発者から出た “その疑問” にズバリお答えします !] の [\第 2 回 プログラミングに関する Tips 1] に記載されています。
今回は 1 行目の INSERT で使用している[??] という漢字がポイントとなります。
# 2 行目に INSERT している文字は Shift JIS でも存在している文字が使用されています。
最初に INSERT しているデータでは [??] という文字を使用しています。これは、IME で変換するときに環境依存文字とされています。
この文字はサロゲートペアの文字列となっており、16 ビット + 16 ビットの文字で構成されています。
IME パッドを使用するとコードが見れるのですが、[U+D842] と [U+DF9F] で構成されている文字になります。
これに対して、[叱] は 16 ビットの文字 (U+53F1) となっています。
この文字を使用して新規に追加された照合順序の動作を確認していきます。
1 の動作確認
UTF-16 サロゲート ペアは、1 つのコード ポイントとしてカウントされます。
これを確認するために以下のクエリを実行してみます。
SELECT LEN(Col1), LEN(Col2), * FROM TblTest |
実行結果がこちらです。
今回確認するポイントは 1 行目の結果となります。
Japanese_XJIS_100_CI_AS を使用している場合は文字数が 6 となっており、Japanese_XJIS_100_CI_AS_SC の場合は5 となっています。
このデータは 5 つの文字で構成されていますので LEN の結果は 5 となるのが正しいですがSQL Server 2008 R2 までの照合順序ではサロゲートペア文字は文字数が 2 の文字となってしまいます。
# 上位サロゲートと下位サロゲートがそれぞれ一文字と数えられているのかと。
SQL Server 2012 で導入された SC を使用するとサロゲートペアの文字も 1 文字としてカウントされるようになります。
2 の動作確認
これらの関数は、各サロゲート ペアを 1 つのコード ポイントとして処理し、期待どおりに動作します。
これを確認するために以下のクエリを実行してみます。
SELECT LEFT(Col1, 4), LEFT(Col2, 4), * FROM TblTest |
SC の照合順序が使用されている場合はサロゲートペアの文字が含まれていても正常に文字列の切り出しが行えています。
3 の動作確認
0 ~ 0x10FFFF の範囲の指定した Unicode コード ポイント値に対応する文字を返します。指定された値が 0 ~ 0xFFFF の範囲内にある場合、1 つの文字だけが返されます。値が大きい場合、対応するサロゲート ペアが返されます。
サロゲートペアの [] は INT で表現すると 134047 (20B9F) になりますので以下のクエリを実行します。
SELECT NCHAR(134047) |
このクエリは現在選択されているデータベースに依存して結果が変わってきます。
データベースの照合順序として Japanese_XJIS_100_CI_AS が設定されている場合は結果が NULL となります。
SC の照合順序が設定されているデータベースではサロゲートペアの文字を正常に値を取得することができます。
4 の動作確認
0 から 0x10FFFF の範囲の UTF-16 コード ポイントが返されます
これは先ほどと逆で文字のコードポイントを求めるので以下のクエリを実行します。
SELECT UNICODE(N’??’) |
こちらも実行しているデータベースの照合順序に結果が依存します。
データベースの照合順序として Japanese_XJIS_100_CI_AS が設定されている場合は以下の結果となります。
55362 は 16 進数にすると D842 となります。
は [U+D842] と [U+DF9F] で構成されていますが、Japanese_XJIS_100_CI_AS を使用している場合は上位サロゲートのコードのみが帰ってきています。
CS が設定されている場合は、134047 (20B9F) が取得されています。
[??] を IME パッドで確認すると 20B9F にある文字となっていますので、SC を設定している場合は正しい値が取得できていますね。
5 の動作確認
補助文字は、すべてのワイルドカード操作でサポートされています。
これを確認するためには LIKE 検索で [_] を使用します。
# % を使用したワイルドカード検索は Japanese_XJIS_100_CI_AS でも正常に結果が取得できているはずです。
SELECT * FROM TblTest WHERE Col1 LIKE N’森?外_る’ SELECT * FROM TblTest WHERE Col2 LIKE N’森?外_る’ |
実行結果がこちらになります。
Col1 と Col2 には同じ文字列が格納されていますが、LIKE の検索結果が変わっています。
Japanese_XJIS_100_CI_AS を使用している列で検索した場合はサロゲートペアの文字が 1 文字と認識できずに結果が無い状態になっています。
この照合順序の場合は以下のクエリを実行すると結果を取得することができます。
# サロゲートペアの文字の箇所を 2 文字としてワイルドカードで検索しています。
SELECT * FROM TblTest WHERE Col1 LIKE N’森?外__る’ |
CS を設定した場合はサロゲートペアの文字を 1 文字として認識できているため正常に結果が取得できています。
SQL Server 2012 で追加された補助文字用の照合順序を使用するとサロゲートペアに対しての文字列処理の挙動が変わる (想定した結果が返ってくるようになる) のが確認できました。
BOL で一覧になっているのでどのように動作が変わるのかは把握しやすいのですが自分で試しながら軽くまとめてみました。
SQL Server 2012 で追加された照合順序で何ができるようになった? ≪ SE の雑記…
素敵なエントリーの登録ありがとうございます – .NET Clipsからのトラックバック…
.NET Clips
29 5月 12 at 10:16