各文字列リテラルには文字セットと照合順序があります。
文字列リテラルでは、オプションとして文字セットイントロデューサと COLLATE
句を指定できます。
[_charset_name]'string' [COLLATE collation_name]
例:
SELECT 'string';
SELECT _latin1'string';
SELECT _latin1'string' COLLATE latin1_danish_ci;
単純なステートメント SELECT '
に対して、文字列には string
'character_set_connection
および collation_connection
システム変数で定義された文字セットと照合順序が適用されます。
_
式は正式にはイントロデューサと呼ばれます。これは、「後続する文字列が文字セット charset_name
X
を使用する」ことをパーサーに通知します。わかりにくいので強調しておきますが、イントロデューサは、CONVERT()
が行うようなイントロデューサ文字セットへの文字列の変換は行いません。パディングが行われる可能性がありますが、文字列の値は変更しません。イントロデューサは単なる信号です。イントロデューサは、標準の 16 進リテラルおよび数値の 16 進リテラル表記 (x'
および literal
'0x
) の前でも、ビットフィールドリテラル表記 (nnnn
b'
および literal
'0b
) の前でも有効です。
nnnn
例:
SELECT _latin1 x'AABBCC';
SELECT _latin1 0xAABBCC;
SELECT _latin1 b'1100011';
SELECT _latin1 0b1100011;
MySQL では、リテラルの文字セットおよび照合順序が次のように決定されます。
_X
とCOLLATE
の両方が指定されている場合、文字セットY
X
と照合順序Y
が使用されます。_X
は指定されているが、COLLATE
が指定されていない場合、文字セットX
とそのデフォルト照合順序が使用されます。各文字セットのデフォルトの照合順序を確認するには、SHOW COLLATION
ステートメントを使用します。これ以外の場合は、
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
(セクション10.1.4「接続文字セットおよび照合順序」で説明しているように、character_set_connection
を変更します) を使用し、正確な文字列の内容を確認できるように 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
」が続いています。このエスケープシーケンスは、latin1
の character_set_connection
値を使用して解釈され、リテラルの改行 (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
です。この文字セットでは、「à
」のあとに「\
」 (16 進値 05
および 5C
) が続いたシーケンスは、有効なマルチバイト文字になります。したがって、文字列の最初の 2 バイトは、単一の sjis
文字として解釈され、「\
」はエスケープ文字として解釈されません。後続の「n
」 (16 進値 6E
) はエスケープシーケンスの一部としては解釈されません。これは 2 番目の文字列にも当てはまります。_latin1
のイントロデューサはエスケープ処理に影響を及ぼしません。