字元集的範圍是指該集中字元的集合。
字串運算式具有範圍屬性,可以有兩個值
ASCII
:運算式只能包含 ASCII 字元;也就是 Unicode 範圍U+0000
到U+007F
中的字元。UNICODE
:運算式可以包含 Unicode 範圍U+0000
到U+10FFFF
中的字元。這包括基本多文種平面 (BMP) 範圍中的字元 (U+0000
到U+FFFF
) 和 BMP 範圍外的補充字元 (U+10000
到U+10FFFF
)。
ASCII
範圍是 UNICODE
範圍的子集,因此具有 ASCII
範圍的字串可以安全地轉換為任何具有 UNICODE
範圍的字串字元集,而不會遺失資訊。它也可以安全地轉換為任何是 ascii
字元集超集的字元集。(除了 swe7
以外,所有 MySQL 字元集都是 ascii
的超集,swe7
會將一些標點符號字元重新用於瑞典語重音字元。)
在校對強制轉換規則不足以解決歧義的情況下,使用範圍可以在運算式中進行字元集轉換,否則 MySQL 會傳回「不合法的校對混合」錯誤。(有關強制轉換性的資訊,請參閱第 12.8.4 節,〈運算式中的校對強制轉換性〉。)
以下討論提供運算式及其範圍的範例,並說明使用範圍如何變更字串運算式評估
字串常數的範圍取決於字串內容,並且可能與字串字元集的範圍不同。請考慮以下陳述式
SET NAMES utf8mb4; SELECT 'abc'; SELECT _utf8mb4'def';
儘管在上述每個案例中,字元集都是
utf8mb4
,但字串實際上不包含任何超出 ASCII 範圍的字元,因此它們的範圍是ASCII
而不是UNICODE
。由於字元集的關係,具有
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 | +---------------+
具有一個字串引數的函數會繼承其引數的範圍。
UPPER(_utf8mb4'abc')
的結果具有ASCII
範圍,因為其引數具有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
更廣泛。請考慮以下CONCAT()
呼叫CONCAT(_ucs2 X'0041', _ucs2 X'0042') CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
對於第一個呼叫,範圍是
ASCII
,因為兩個引數都在 ASCII 範圍內。對於第二個呼叫,範圍是UNICODE
,因為第二個引數超出 ASCII 範圍。函數傳回值的範圍是根據僅會影響結果字元集和校對的那些引數的範圍來判斷。
IF(column1 < column2, 'smaller', 'greater')
結果範圍是
ASCII
,因為兩個字串引數 (第二個引數和第三個引數) 都具有ASCII
範圍。第一個引數對於結果範圍並不重要,即使運算式使用字串值也一樣。