各文字列リテラルにはキャラクタセットと照合順序があります。
文字列リテラルでは、オプションとしてキャラクタセットイントロデューサと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_nameXの文字列が後続する」ことがパーサに通知されます。上記はユーザの混乱を招いていたため、ここで強調しておきますが、イントロデューサは変換の原因にはならず、文字列の値が変更されないことを示すにすぎません。標準的な16進リテラルおよび数値16進リテラルの表記(x'およびliteral'0x)の前でも、イントロデューサは有効です。
nnnn
例:
SELECT _latin1 x'AABBCC'; SELECT _latin1 0xAABBCC;
MySQLでは、リテラルのキャラクタセットおよび照合順序が次のように決定されます。
_XとCOLLATE
の両方が指定された場合、リテラルキャラクタセットはYX、リテラル照合順序は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_connectionlatin1
の値を使い、新しいリテラルニューラインを作成します。(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のイントロデューサはエスケーププロセッシングに影響しません。
