Unicode文字と非Unicode文字を連結する
from SQL Serverの文字列型varchar nvarchar
テーブルに格納しない文字列を取得して、連結してみる
code:sql
SELECT 'A'; -- ここで連結してみる
上記のSELECTでの推測と予想
1. NプレフィックスなしでSELECTすると…
デフォルトコードページの文字コード(CP932)で呼ばれる?
ぽい(後述)
テーブルから取得しないということは、コードページはどう決まる?
上位の設定?
サーバー自体の照合順序に従ったコードページかな?
ぽい(後述)
2. NプレフィックスありでSELECTすると…
Unicode文字として呼ばれる?
ぽい(後述)
3. NなしとNありを連結すると…
暗黙の型変換が起きる?
起こっているように見える(後述)
4. NありとNありを連結すると…
Unicode文字同士の文字列連結がされる?
できている(後述)
実際に試した結果
1. NプレフィックスなしでSELECTすると…
code:sql
SELECT 'A',
LEN('A') AS length, DATALENGTH('A') AS data_length, CAST('A' AS varbinary(max)) AS bin;
SELECT '愛',
LEN('愛') AS length, DATALENGTH('愛') AS data_length, CAST('愛' AS varbinary(max)) AS bin;
SELECT '𩸽',
LEN('𩸽') AS length, DATALENGTH('𩸽') AS data_length, CAST('𩸽' AS varbinary(max)) AS bin;
SELECT 'A' + '𩸽',
LEN('A' + '𩸽') AS length, DATALENGTH('A' + '𩸽') AS data_length, CAST('A' + '𩸽' AS varbinary(max)) AS bin;
table:result
__COLUMN1 length data_length bin
A 1 1 41
__COLUMN1 length data_length bin
愛 1 2 88A4
__COLUMN1 length data_length bin
?? 2 2 3F3F
__COLUMN1 length data_length bin
A?? 3 3 413F3F
AはShift_JIS(CP932)だと0x41
愛はShift_JIS(CP932)だと0x88A4
CP932っぽいな
サーバーの設定はどうやって確認するんだ?
SERVERPROPERTYかな?
code:sql
SELECT
SERVERPROPERTY('InstanceName') AS InstanceName
, SERVERPROPERTY('MachineName') AS MachineName
, SERVERPROPERTY('Collation') AS Collation
, SERVERPROPERTY('CollationID') AS CollationID
, SERVERPROPERTY('ComparisonStyle') AS ComparisonStyle
, SERVERPROPERTY('LCID') AS LCID
, SERVERPROPERTY('SqlCharSet') AS SqlCharSet
, SERVERPROPERTY('SqlCharSetName') AS SqlCharSetName
, SERVERPROPERTY('SqlSortOrder') AS SqlSortOrder
, SERVERPROPERTY('SqlSortOrderName') AS SqlSortOrderName
;
table:result
InstanceName MachineName Collation Colla(略) Compar(略) LCID SqlCh(略) SqlCh(略) SqlSo(略) SqlSo(略)
« NULL » sample Japanese_CI_AS 53264 196609 1041 109 cp932 0 bin_ascii_8
これでCP932確認できたことになる?
COLLATIONPROPERTYでJapanese_CI_ASの情報も確認できる?
code:sql
SELECT
name
, COLLATIONPROPERTY(name, 'CodePage') AS CodePage
, COLLATIONPROPERTY(name, 'LCID') AS LCID
, COLLATIONPROPERTY(name, 'ComparisonStyle') AS ComparisonStyle
, COLLATIONPROPERTY(name, 'Version') AS Version
FROM
sys.fn_helpcollations()
WHERE
name = 'Japanese_CI_AS'
;
table:result
name CodePage LCID ComparisonStyle Version
Japanese_CI_AS 932 1041 196609 0
コードページ932
2. NプレフィックスありでSELECTすると…
code:sql
SELECT N'A',
LEN(N'A') AS length, DATALENGTH(N'A') AS data_length, CAST(N'A' AS varbinary(max)) AS bin;
SELECT N'𩸽',
LEN(N'𩸽') AS length, DATALENGTH(N'𩸽') AS data_length, CAST(N'𩸽' AS varbinary(max)) AS bin;
table:result
__COLUMN1 length data_length bin
A 1 2 4100
__COLUMN1 length data_length bin
𩸽 2 4 67D83DDE
AはUTF-16BEだと0x0041
𩸽はUTF-16BEだと0xD867DE3D
3. NなしとNありを連結すると…
暗黙の型変換が起こっているように見える
code:sql
SELECT 'A' + N'𩸽',
LEN('A' + N'𩸽') AS length, DATALENGTH('A' + N'𩸽') AS data_length, CAST('A' + N'𩸽' AS varbinary(max)) AS bin;
table:result
__COLUMN1 length data_length bin
A𩸽 3 6 410067D83DDE
Aが0x4100になっているのでCP932からUnicodeに変換されているように見える
4.も参考
実際に確認するにはどうすればいいかな
4. NありとNありを連結すると…
Unicode文字同士の文字列連結がされている
code:sql
SELECT N'A' + N'𩸽',
LEN(N'A' + N'𩸽') AS length, DATALENGTH(N'A' + N'𩸽') AS data_length, CAST(N'A' + N'𩸽' AS varbinary(max)) AS bin;
table:result
__COLUMN1 length data_length bin
A𩸽 3 6 410067D83DDE
これがUnicode文字同士の連結結果なので予想通り
そして、3.の結果と同じなので3.もUnicode文字同士の連結になっているように見える