排序規(guī)則的優(yōu)先順序(也稱為排序規(guī)則類型強制規(guī)則)是賦予一組規(guī)則的術(shù)語,而這組規(guī)則決定:
排序規(guī)則的優(yōu)先順序規(guī)則只適用于字符串?dāng)?shù)據(jù)類型:char、varchar、text、nchar、nvarchar 和 ntext。具有其它數(shù)據(jù)類型的對象不參加排序規(guī)則的評估。
所有對象的排序規(guī)則可歸為四類中的一種。每類的名稱叫做排序規(guī)則標(biāo)志。
排序規(guī)則標(biāo)志 | 對象類型 |
強制默認(rèn) | 任何 Transact-SQL 字符串變量、參數(shù)、字面值、目錄內(nèi)置函數(shù)的輸出、或不使用字符串輸入但產(chǎn)生字符串輸出的內(nèi)置函數(shù)。 如果在用戶定義函數(shù)、存儲過程或觸發(fā)器中聲明某個對象,則將該對象指派為在其中創(chuàng)建函數(shù)、存儲過程或觸發(fā)器的數(shù)據(jù)庫的默認(rèn)排序規(guī)則。如果在批處理中聲明該對象,則將其指派為連接所使用的當(dāng)前數(shù)據(jù)庫的默認(rèn)排序規(guī)則。 |
隱性 X | 列引用。從為表或視圖中的列定義的排序規(guī)則得到表達(dá)式(由 X 表示)的排序規(guī)則。 即使 CREATE TABLE 或 CREATE VIEW 語句中的 COLLATE 子句給列顯式指派了排序規(guī)則,該列引用仍歸為隱性。 |
顯式 X | 使用表達(dá)式中的 COLLATE 子句顯式投影到特定排序規(guī)則(由 X 表示)的表達(dá)式。 |
無排序規(guī)則 | 表示表達(dá)式的值是兩個字符串之間操作的結(jié)果,而這兩個字符串具有隱性排序規(guī)則標(biāo)志的沖突排序規(guī)則。表達(dá)式的結(jié)果被定義為不具有排序規(guī)則。 |
只引用一個字符串對象的簡單表達(dá)式的排序規(guī)則標(biāo)志是被引用對象的排序規(guī)則標(biāo)志。
如果復(fù)雜表達(dá)式所引用的兩個操作數(shù)表達(dá)式的排序規(guī)則標(biāo)志相同,則該復(fù)雜表達(dá)式的排序規(guī)則標(biāo)志為數(shù)表達(dá)式的排序規(guī)則標(biāo)志。
如果復(fù)雜表達(dá)式所引用的兩個操作數(shù)表達(dá)式的排序規(guī)則不同,則該復(fù)雜表達(dá)式最終結(jié)果的排序規(guī)則標(biāo)志基于下列規(guī)則:
顯式 > 隱性 > 強制默認(rèn)
顯式 X + 顯式 Y = 錯誤
隱性 X + 隱性 Y = 無排序規(guī)則
無排序規(guī)則 + 任何標(biāo)志 = 無排序規(guī)則
無排序規(guī)則 + 顯式 X = 顯式
下面的示例說明上述規(guī)則。
USE tempdb
GO
CREATE TABLE TestTab (
id int,
GreekCol nvarchar(10) collate greek_ci_as,
LatinCol nvarchar(10) collate latin1_general_cs_as
)
INSERT TestTab VALUES (1, N'A', N'a')
GO
下面查詢中的謂詞具有排序規(guī)則沖突,因此產(chǎn)生錯誤:
SELECT *
FROM TestTab
WHERE GreekCol = LatinCol
下面是結(jié)果集。
Msg 446, Level 16, State 9, Server CTSSERV, Line 1
Cannot resolve collation conflict for equal to operation.
下面查詢中的謂詞在排序規(guī)則 greek_ci_as 中取值,因為右邊表達(dá)式具有顯式標(biāo)志,優(yōu)先于右邊表達(dá)式的隱性標(biāo)志:
SELECT *
FROM TestTab
WHERE GreekCol = LatinCol COLLATE greek_ci_as
下面是結(jié)果集。
id GreekCol LatinCol
----------- -------------------- --------------------
1 a A
(1 row affected)
下面查詢中的 case 表達(dá)式?jīng)]有排序規(guī)則標(biāo)志,所以不能出現(xiàn)在選擇列表中,也不能由區(qū)分排序規(guī)則的運算符操作。不過,這些表達(dá)式可由不區(qū)分排序規(guī)則的運算符操作。
SELECT (CASE WHEN id > 10 THEN GreekCol ELSE LatinCol END)
FROM TestTab
下面是結(jié)果集。
Msg 451, Level 16, State 1, Line 1
Cannot resolve collation conflict for column 1 in SELECT statement.
SELECT PATINDEX((CASE WHEN id > 10 THEN GreekCol ELSE LatinCol END), 'a')
FROM TestTab
下面是結(jié)果集。
Msg 446, Level 16, State 9, Server LEIH2, Line 1
Cannot resolve collation conflict for patindex operation.
SELECT (CASE WHEN id > 10 THEN GreekCol ELSE LatinCol END) COLLATE Latin1_General_CI_AS
FROM TestTab
下面是結(jié)果集。
--------------------
a
(1 row affected)
下表匯總了上述規(guī)則。
操作數(shù)強制標(biāo)志 | 顯式 X | 隱性 X | 強制默認(rèn) | 無排序規(guī)則 |
顯式 Y | 生成錯誤 | 結(jié)果為顯式 Y | 結(jié)果為顯式 Y | 結(jié)果為顯式 Y |
隱性 Y | 結(jié)果為顯式 X | 結(jié)果為無排序規(guī)則 | 結(jié)果為隱性 Y | 結(jié)果為無排序規(guī)則 |
強制默認(rèn) | 結(jié)果為顯式 X | 結(jié)果為隱性 X | 結(jié)果為強制默認(rèn) | 結(jié)果為無排序規(guī)則 |
無排序規(guī)則 | 結(jié)果為顯式 X | 結(jié)果為無排序規(guī)則 | 結(jié)果為無排序規(guī)則 | 結(jié)果為無排序規(guī)則 |
運算符和函數(shù)區(qū)分排序規(guī)則或不區(qū)分排序規(guī)則:
比較運算符以及 MAX、MIN、BETWEEN、LIKE 和 IN 運算符都區(qū)分排序規(guī)則。運算符所使用的字符串被賦以具有較高優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。UNION 運算符也區(qū)分排序規(guī)則,且所有的字符串操作數(shù)和最終結(jié)果被賦以具有最高優(yōu)先順序的操作數(shù)的排序規(guī)則。按列評估 UNION 操作數(shù)和結(jié)果的排序規(guī)則優(yōu)先順序。
賦值運算符不區(qū)分排序規(guī)則,右邊的表達(dá)式投影到左邊的排序規(guī)則上。
字符串串聯(lián)運算符不區(qū)分排序規(guī)則,兩個字符串操作數(shù)和結(jié)果被賦以具有最高排序規(guī)則優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。UNION ALL 和 CASE 運算符不區(qū)分排序規(guī)則,所有的字符串操作數(shù)和最終結(jié)果都被賦以具有最高優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。按列評估 UNION ALL 操作數(shù)和結(jié)果的排序規(guī)則優(yōu)先順序。
CAST、CONVERT 和 COLLATE 函數(shù)區(qū)分 char、varchar 和 text 數(shù)據(jù)類型的排序規(guī)則。如果 CAST 和 CONVERT 函數(shù)的輸入和輸出是字符串,則輸出字符串具有輸入字符串的排序規(guī)則標(biāo)志。如果輸入不是字符串,則輸出字符串為強制默認(rèn)并被賦以連接所使用的當(dāng)前數(shù)據(jù)庫的排序規(guī)則,或是包含引用 CAST 或 CONVERT 的用戶定義函數(shù)、存儲過程或觸發(fā)器的數(shù)據(jù)庫的排序規(guī)則。
對于返回字符串但不使用字符串輸入的內(nèi)置函數(shù),結(jié)果字符串為強制默認(rèn)并被賦以當(dāng)前數(shù)據(jù)庫的排序規(guī)則,或是包含引用該函數(shù)的用戶定義函數(shù)、存儲過程或觸發(fā)器的數(shù)據(jù)庫的排序規(guī)則。
下列函數(shù)區(qū)分排序規(guī)則,其輸出字符串具有輸入字符串的排序規(guī)則標(biāo)志:
下列附加規(guī)則也適用于排序規(guī)則優(yōu)先順序:
WHERE ColumnA = ( 'abc' COLLATE French_CI_AS) COLLATE French_CS_AS
在數(shù)據(jù)類型轉(zhuǎn)換后確定排序規(guī)則的優(yōu)先順序。產(chǎn)生結(jié)果排序規(guī)則的操作數(shù)可以與提供最終結(jié)果數(shù)據(jù)類型的操作數(shù)不同。例如,考察下面的批處理:
CREATE TABLE TestTab
(PrimaryKey int PRIMARY KEY,
CharCol char(10) COLLATE French_CI_AS
)
SELECT *
FROM TestTab
WHERE CharCol LIKE N'abc'
簡單表達(dá)式 N'abc' 的 Unicode 數(shù)據(jù)類型具有較高的數(shù)據(jù)類型優(yōu)先順序,所以結(jié)果表達(dá)式將 Unicode 數(shù)據(jù)類型指派給 N'abc'。然而,表達(dá)式 CharCol 具有隱性排序規(guī)則標(biāo)志,而 N'abc' 具有較低的強制默認(rèn)排序規(guī)則標(biāo)志,所以使用的排序規(guī)則是 CharCol 的 French_CI_AS 排序規(guī)則。
相關(guān)文章