文字セットのレパートリーとは、そのセット内の文字の集合です。
文字列式にはレパートリー属性があり、その値は次の 2 つです。
ASCII
: 式には ASCII 文字、つまりU+0000
からU+007F
までの Unicode 範囲の文字のみを含めることができます。UNICODE
:U+0000
からU+10FFFF
の Unicode 範囲内の文字を式に含めることができます。 これには、Basic Multilingual Plane (BMP) 範囲 (U+0000
からU+FFFF
) の文字と BMP 範囲外の補助文字 (U+10000
からU+10FFFF
) が含まれます。
ASCII
範囲は UNICODE
範囲のサブセットであるため、ASCII
レパートリーを含む文字列は、情報を失うことなく、UNICODE
レパートリーを含む文字列の文字セットに安全に変換できます。 また、ascii
文字セットのスーパーセットである任意の文字セットに安全に変換できます。 (すべての MySQL 文字セットは、swe7
を除いて ascii
のスーパーセットであり、スウェーデン語アクセント付き文字に一部の句読点文字が再利用されます。)
レパートリーを使用すると、照合強制性のルールがあいまいさを解決するには不十分な場合に MySQL が「「照合順序の組合せが不正です」」エラーを返す多くの場合に、式で文字セット変換が可能になります。 (強制性の詳細は、セクション10.8.4「式での照合の強制性」 を参照してください。)
次の説明では、式とそのレパートリーの例を挙げ、レパートリーの使用によって、文字列式の評価がどのように変わるかを示します。
-
文字列定数のレパートリーは文字列の内容に依存し、文字列文字セットのレパートリーとは異なる場合があります。 これらのステートメントを考慮してください。
SET NAMES utf8mb4; SELECT 'abc'; SELECT _utf8mb4'def';
前述の各場合、文字セットは
utf8mb4
ですが、文字列には実際に ASCII 範囲外の文字が含まれていないため、そのレパートリーはUNICODE
ではなくASCII
です。 -
ascii
文字セットを持つカラムには、その文字セットのためにASCII
レパートリーがあります。 次のテーブルでは、c1
にはASCII
レパートリーがあります。CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);
次の例では、レパートリーがないときにエラーが発生する場合に、レパートリーによってどのように結果が求められるようになるかを示しています。
CREATE TABLE t1 ( c1 CHAR(1) CHARACTER SET latin1, c2 CHAR(1) CHARACTER SET ascii ); INSERT INTO t1 VALUES ('a','b'); SELECT CONCAT(c1,c2) FROM t1;
レパートリーがない場合、次のエラーが発生します。
ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (ascii_general_ci,IMPLICIT) for operation 'concat'
レパートリーを使用すると、サブセットからスーパーセットへ (
ascii
からlatin1
へ) の変換を行うことができ、結果が返されます。+---------------+ | CONCAT(c1,c2) | +---------------+ | ab | +---------------+
1 つの文字列引数を持つ関数は、その引数のレパートリーを継承します。 引数に
ASCII
レパートリーがあるため、UPPER(_utf8mb4'abc')
の結果にはASCII
レパートリーがあります。 (_utf8mb4
イントロデューサにもかかわらず、文字列'abc'
に ASCII 範囲外の文字が含まれていません。)-
文字列を返すが、文字列引数を持たず、結果文字セットとして
character_set_connection
を使用する関数の場合、結果のレパートリーは、character_set_connection
がascii
である場合はASCII
に、それ以外の場合はUNICODE
になります。FORMAT(numeric_column, 4);
レパートリーを使用するかどうかによって、MySQL が次の例をどのように評価するかが変わります。
SET NAMES ascii; CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1); INSERT INTO t1 VALUES (1,'b'); SELECT CONCAT(FORMAT(a, 4), b) FROM t1;
レパートリーがない場合、次のエラーが発生します。
ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'concat'
レパートリーを使用すると、次のように結果が返されます。
+-------------------------+ | CONCAT(FORMAT(a, 4), b) | +-------------------------+ | 1.0000b | +-------------------------+
-
複数の文字列引数を持つ関数は、
UNICODE
がASCII
よりも広い場合に、結果レパートリーに「「ワイドスト」」引数 repertoire を使用します。 次のCONCAT()
呼び出しを考えてみます。CONCAT(_ucs2 X'0041', _ucs2 X'0042') CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
最初のコールでは、両方の引数が ASCII 範囲内にあるため、レパートリーは
ASCII
です。 2 番目のコールでは、2 番目の引数が ASCII 範囲外であるため、レパートリーはUNICODE
です。 -
関数の戻り値のレパートリーは、結果の文字セットおよび照合順序に影響する引数のみのレパートリーに基づいて決定されます。
IF(column1 < column2, 'smaller', 'greater')
結果のレパートリーは、2 つの文字列引数 (2 番目の引数と 3 番目の引数) がどちらも
ASCII
レパートリーなので、ASCII
です。 最初の引数は、式で文字列値を使用する場合でも、結果のレパートリーにとっては重要ではありません。