web-dev-qa-db-ja.com

Unicode文字が置換されない場合があるのはなぜですか?

これを実行すると、期待どおりに「テスト」が行われます。

SELECT
    REPLACE(NCHAR(1234), NCHAR(1234), N'test');

ただし、これを実行すると「aӒa」が生成され、「test」が含まれていません。

SELECT
    REPLACE(N'a' + NCHAR(1234) + N'a', NCHAR(1234), N'test');

針ではなく、干し草の山で発生する文字列の連結に関係があるのではないかと思ったのですが、これを試してもまだ機能しませんでした。

SELECT
    REPLACE(N'a' + NCHAR(1234) + N'a', N'' + NCHAR(1234) + N'', N'test');

結果:「aӒa」

私はそれが文字の解釈方法に関係しているのではないかと思ったので、バイナリ照合を指定してみました...それで問題が「修正」されました。

SELECT
    REPLACE(N'a' + NCHAR(1234) + N'a' COLLATE Latin1_General_100_BIN2, NCHAR(1234), N'test');

結果:「アテスタ」。

どうして?

この動作は、一部のキャラクターには存在するようですが、他のキャラクターには存在しません。

SELECT
    REPLACE(N'a' + NCHAR(23423) + N'a', NCHAR(23423), N'test');

結果: "atesta"( "作品")

SELECT
    REPLACE(N'a' + NCHAR(5342) + N'a', NCHAR(5342), N'test');

結果:「aᓞa」(「機能しない」)

どうして?

4
Riley Major

この動作は、 "100"より前のシリーズのデフォルトの照合順序を持つデータベースでクエリを実行しているために発生します。この場合、非常に多くの文字に並べ替えの重みがありません。並べ替えの重みがないということは、空の文字列と同等であることを意味します。これらの値は0です。したがって、ソートの重みを持つものが他に関係していない場合、それらは常に互いに等しくなります。また、空の文字列と同じです。バージョン100の照合順序(SQL Server 2008以降、バージョン10.0または100の10進数/マイナーバージョンなし)では、ほとんどの文字に並べ替えの重みが追加されました。したがって、_COLLATE Latin1_General_100_CI_AS_SC_を追加して照合を強制するだけです。任意のバージョンのバイナリ照合順序(__BIN2_で終わるもの、__BIN_だけで終わる照合順序を使用しない)も機能します。これは、バイナリ照合順序に並べ替えの重みなどがないためです。

_SELECT 1 WHERE NCHAR(1234) = '' COLLATE SQL_Latin1_General_CP1_CI_AS;
-- 1

SELECT 2 WHERE NCHAR(1234) = '' COLLATE Latin1_General_CI_AS;
-- 2

SELECT 3 WHERE NCHAR(1234) = '' COLLATE Latin1_General_100_CI_AS;
-- (no results)

SELECT 4 WHERE NCHAR(1234) = '' COLLATE Latin1_General_BIN2;
-- (no results)
_

重みのない複数の文字でも空の文字列(または並べ替えの重みのない任意の数の文字)と同等です。

_SELECT 5 WHERE NCHAR(1234) + NCHAR(1234) + NCHAR(1234)
       = N'' COLLATE Latin1_General_CS_AS_KS_WS;
-- 5
_

この次のテストでは、NCHAR(1234)は、バージョン100(またはそれ以降)の照合順序を使用する場合にのみ、それ自体と同等です。バージョン100より前の照合順序では、NCHAR(1234)に並べ替えの重みが割り当てられないため、何にも等しくないため、最初の式には含まれていませんでした。

_SELECT REPLACE(N'a' + NCHAR(1234) + N'a',
               NCHAR(1234) COLLATE Latin1_General_100_CI_AS,
               N'test');
-- atesta
_

上記の例5を続けると、重みのない3文字が、重みのない2つの異なる文字と等しいことを証明できます。

_SELECT 6 WHERE NCHAR(1234) + NCHAR(1234) + NCHAR(1234)
             = NCHAR(5342) + NCHAR(5342) COLLATE Latin1_General_CS_AS_KS_WS;
-- 6
_

しかし、バージョン100照合に切り替えると、次のように変わります。

_SELECT 7 WHERE NCHAR(1234) + NCHAR(1234) + NCHAR(1234)
             = NCHAR(5342) + NCHAR(5342) COLLATE Latin1_General_100_CS_AS_KS_WS;
-- (no results)

SELECT 8 WHERE NCHAR(1234) = NCHAR(5342) COLLATE Latin1_General_100_CS_AS_KS_WS;
-- (no results)
_

私の次の投稿の「補足文字」の文字セクションを参照してください。そのセクションでは、補助文字に関連する同様の動作を示し、セクションの最後に、これらの「欠けている重み」の1つに一致するBMP文字(つまり、非補助文字)の文字数を示します。 "照合バージョンごとの文字。

The Uni-Code:The Search for the True List of Valid Characters for T-SQL Identifiers、Part 3 of 2(Delimited Identifiers)

照合の操作の詳細については、次のWebサイトをご覧ください Collat​​ions.info

6
Solomon Rutzky