各文字列リテラルにはキャラクタセットと照合順序があります。
文字列リテラルでは、オプションとしてキャラクタセットイントロデューサとCOLLATE
節を指定することができます。
[_charset_name
]'string
' [COLLATEcollation_name
]
例:
SELECT 'string
'; SELECT _latin1'string
'; SELECT _latin1'string
' COLLATE latin1_danish_ci;
単純なステートメントSELECT
'
に対して、文字列にはstring
'character_set_connection
およびcollation_connection
システム変数で定義されたキャラクタセットと照合順序が存在します。
_
は形式上イントロデューサと呼ばれています。指定すると、「キャラクタセットcharset_name
X
の文字列が後続する」ことがパーサに通知されます。上記はユーザの混乱を招いていたため、ここで強調しておきますが、イントロデューサは変換の原因にはならず、文字列の値が変更されないことを示すにすぎません。標準的な16進リテラルおよび数値16進リテラルの表記(x'
およびliteral
'0x
)の前でも、イントロデューサは有効です。
nnnn
例:
SELECT _latin1 x'AABBCC'; SELECT _latin1 0xAABBCC;
MySQLでは、リテラルのキャラクタセットおよび照合順序が次のように決定されます。
_X
とCOLLATE
の両方が指定された場合、リテラルキャラクタセットはY
X
、リテラル照合順序はY
。
_X
は指定されており、COLLATE
が指定されていない場合、リテラルキャラクタセットはX
、リテラル照合順序はそのデフォルト照合順序。
その他の場合は、character_set_connection
およびcollation_connection
システム変数が指定するリテラルキャラクタセットとリテラル照合順序。
例:
文字列にlatin1
キャラクタセットとlatin1_german1_ci
照合順序が指定されている場合
SELECT _latin1'Müller' COLLATE latin1_german1_ci;
文字列にlatin1
キャラクタセットとそのデフォルト照合順序(latin1_swedish_ci
)が指定されている場合
SELECT _latin1'Müller';
文字列に接続デフォルトキャラクタセットおよび照合順序が指定されている場合
SELECT 'Müller';
キャラクタセットイントロデューサとCOLLATE
節は、標準SQLの指定に基づいて提供されています。
イントロデューサは後続の文字列に対してキャラクタセットを指定しますが、現在のところ、その文字列におけるパーサのエスケーププロセス内容までは変更しません。エスケープは常に、character_set_connection
に指定されたキャラクタセットに従ってパーサが実行します。
以下の例は、イントロデューサが存在してもcharacter_set_connection
によるエスケーププロセスが生じる場合についてです。例ではSET
NAMES
(character_set_connection
を変更する項9.4. 「接続のキャラクタセットおよび照合順序」),
を用いてHEX()
ファンクションを使い結果文字列を表示させることで、正確文字列の内容を確認することができます。.
例1:
mysql>SET NAMES latin1;
Query OK, 0 rows affected (0.01 sec) mysql>SELECT HEX('à\n'), HEX(_sjis'à\n');
+------------+-----------------+ | HEX('à\n') | HEX(_sjis'à\n') | +------------+-----------------+ | E00A | E00A | +------------+-----------------+ 1 row in set (0.00 sec)
ここでは ‘à
’
(16進E0
)
の後に‘\n
’ニューラインのエスケープシーケンスが続きます。エスケープシーケンスはcharacter_set_connection
latin1
の値を使い、新しいリテラルニューラインを作成します。(16進
0A
)。これは2番目の文字列にも起こります。つまり、_sjis
のイントロデューサはパーサのエスケーププロセスに影響を及ぼしません。
例2:
mysql>SET NAMES sjis;
Query OK, 0 rows affected (0.00 sec) mysql>SELECT HEX('à\n'), HEX(_latin1'à\n');
+------------+-------------------+ | HEX('à\n') | HEX(_latin1'à\n') | +------------+-------------------+ | E05C6E | E05C6E | +------------+-------------------+ 1 row in set (0.04 sec)
ここでは character_set_connection
は
sjis
になります。このキャラクタセットは次のシーケンス‘à
’
と‘\
’ (hex values
05
and 5C
)がつづく、
有効なマルチバイトキャラクタです。よって、文字列の最初の2バイトは1つのsjis
キャラクタとして実行され、‘\
’
はエスケープキャラクタとし実行されない。次の‘n
’
(16進値6E
)
はエスケープシーケンスの一部として実行されません。これは第2文字列にとっても同様に、_latin1
のイントロデューサはエスケーププロセッシングに影響しません。