在絕大多數陳述式中,MySQL 用來解析比較運算的校對是很明顯的。例如,在下列情況下,應該很清楚校對是資料行 x
的校對
SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;
但是,當有多個運算元時,可能會出現不明確的情況。例如,此陳述式會執行資料行 x
與字串常值 'Y'
之間的比較
SELECT x FROM T WHERE x = 'Y';
如果 x
和 'Y'
具有相同的校對,則用於比較的校對沒有任何不明確之處。但是,如果它們具有不同的校對,則比較應該使用 x
的校對,還是 'Y'
的校對?x
和 'Y'
都有校對,那麼哪個校對優先?
校對混合也可能發生在比較以外的內容中。例如,多引數串連運算 (例如 CONCAT(x,'Y')
) 會合併其引數以產生單一字串。結果應該具有什麼校對?
為了解決這類問題,MySQL 會檢查某個項目的校對是否可以強制轉換為另一個項目的校對。MySQL 會如下指派強制性值
MySQL 會使用下列規則中的強制性值來解決不明確之處
使用強制性值最低的校對。
如果兩者的強制性相同,則
如果兩者都是 Unicode,或兩者都不是 Unicode,則會發生錯誤。
如果其中一方具有 Unicode 字元集,而另一方具有非 Unicode 字元集,則具有 Unicode 字元集的一方會勝出,而且會將自動字元集轉換套用至非 Unicode 的一方。例如,下列陳述式不會傳回錯誤
SELECT CONCAT(utf8mb4_column, latin1_column) FROM t1;
它會傳回具有
utf8mb4
字元集且校對與utf8mb4_column
相同的結果。latin1_column
的值會在串連之前自動轉換為utf8mb4
。對於來自相同字元集的運算元,但混合
_bin
校對與_ci
或_cs
校對的運算,會使用_bin
校對。這類似於混合非二進位和二進位字串的運算如何將運算元評估為二進位字串,而套用於校對而非資料類型。
雖然自動轉換不在 SQL 標準中,但標準確實表示每個字元集 (在支援的字元方面) 都是 Unicode 的「子集」。因為 「適用於超集的內容可以適用於子集」 是眾所周知的原則,所以我們認為 Unicode 的校對可以適用於與非 Unicode 字串的比較。更廣泛而言,MySQL 會使用字元集庫的概念,有時可以用來判斷字元集之間的子集關係,並啟用運算中運算元的轉換,否則會產生錯誤。請參閱第 12.2.1 節「字元集庫」。
下表說明先前規則的一些應用。
比較 | 使用的校對 |
---|---|
column1 = 'A' |
使用 column1 的校對 |
column1 = 'A' COLLATE x |
使用 'A' COLLATE x 的校對 |
column1 COLLATE x = 'A' COLLATE y |
錯誤 |
若要判斷字串表達式的強制性,請使用 COERCIBILITY()
函數 (請參閱第 14.15 節「資訊函數」)
mysql> SELECT COERCIBILITY(_utf8mb4'A' COLLATE utf8mb4_bin);
-> 0
mysql> SELECT COERCIBILITY(VERSION());
-> 3
mysql> SELECT COERCIBILITY('A');
-> 4
mysql> SELECT COERCIBILITY(1000);
-> 5
mysql> SELECT COERCIBILITY(NULL);
-> 6
對於數值或時間值到字串的隱含轉換 (例如在表達式 CONCAT(1, 'abc')
中引數 1
發生),結果會是由 character_set_connection
和 collation_connection
系統變數決定的字元集和校對的字元 (非二進位) 字串。請參閱第 14.3 節「表達式評估中的類型轉換」。