排序規(guī)則的優(yōu)先順序(也稱為排序規(guī)則類型強(qiáng)制規(guī)則)是賦予一組規(guī)則的術(shù)語(yǔ),而這組規(guī)則決定:
排序規(guī)則的優(yōu)先順序規(guī)則只適用于字符串?dāng)?shù)據(jù)類型:char、varchar、text、nchar、nvarchar 和 ntext。具有其它數(shù)據(jù)類型的對(duì)象不參加排序規(guī)則的評(píng)估。
所有對(duì)象的排序規(guī)則可歸為四類中的一種。每類的名稱叫做排序規(guī)則標(biāo)志。
排序規(guī)則標(biāo)志 | 對(duì)象類型 |
強(qiáng)制默認(rèn) | 任何 Transact-SQL 字符串變量、參數(shù)、字面值、目錄內(nèi)置函數(shù)的輸出、或不使用字符串輸入但產(chǎn)生字符串輸出的內(nèi)置函數(shù)。 如果在用戶定義函數(shù)、存儲(chǔ)過(guò)程或觸發(fā)器中聲明某個(gè)對(duì)象,則將該對(duì)象指派為在其中創(chuàng)建函數(shù)、存儲(chǔ)過(guò)程或觸發(fā)器的數(shù)據(jù)庫(kù)的默認(rèn)排序規(guī)則。如果在批處理中聲明該對(duì)象,則將其指派為連接所使用的當(dāng)前數(shù)據(jù)庫(kù)的默認(rèn)排序規(guī)則。 |
隱性 X | 列引用。從為表或視圖中的列定義的排序規(guī)則得到表達(dá)式(由 X 表示)的排序規(guī)則。 即使 CREATE TABLE 或 CREATE VIEW 語(yǔ)句中的 COLLATE 子句給列顯式指派了排序規(guī)則,該列引用仍歸為隱性。 |
顯式 X | 使用表達(dá)式中的 COLLATE 子句顯式投影到特定排序規(guī)則(由 X 表示)的表達(dá)式。 |
無(wú)排序規(guī)則 | 表示表達(dá)式的值是兩個(gè)字符串之間操作的結(jié)果,而這兩個(gè)字符串具有隱性排序規(guī)則標(biāo)志的沖突排序規(guī)則。表達(dá)式的結(jié)果被定義為不具有排序規(guī)則。 |
只引用一個(gè)字符串對(duì)象的簡(jiǎn)單表達(dá)式的排序規(guī)則標(biāo)志是被引用對(duì)象的排序規(guī)則標(biāo)志。
如果復(fù)雜表達(dá)式所引用的兩個(gè)操作數(shù)表達(dá)式的排序規(guī)則標(biāo)志相同,則該復(fù)雜表達(dá)式的排序規(guī)則標(biāo)志為數(shù)表達(dá)式的排序規(guī)則標(biāo)志。
如果復(fù)雜表達(dá)式所引用的兩個(gè)操作數(shù)表達(dá)式的排序規(guī)則不同,則該復(fù)雜表達(dá)式最終結(jié)果的排序規(guī)則標(biāo)志基于下列規(guī)則:
顯式 > 隱性 > 強(qiáng)制默認(rèn)
顯式 X + 顯式 Y = 錯(cuò)誤
隱性 X + 隱性 Y = 無(wú)排序規(guī)則
無(wú)排序規(guī)則 + 任何標(biāo)志 = 無(wú)排序規(guī)則
無(wú)排序規(guī)則 + 顯式 X = 顯式
下面的示例說(shuō)明上述規(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)生錯(cuò)誤:
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 中取值,因?yàn)橛疫叡磉_(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ī)則的運(yùn)算符操作。不過(guò),這些表達(dá)式可由不區(qū)分排序規(guī)則的運(yùn)算符操作。
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ù)強(qiáng)制標(biāo)志 | 顯式 X | 隱性 X | 強(qiáng)制默認(rèn) | 無(wú)排序規(guī)則 |
顯式 Y | 生成錯(cuò)誤 | 結(jié)果為顯式 Y | 結(jié)果為顯式 Y | 結(jié)果為顯式 Y |
隱性 Y | 結(jié)果為顯式 X | 結(jié)果為無(wú)排序規(guī)則 | 結(jié)果為隱性 Y | 結(jié)果為無(wú)排序規(guī)則 |
強(qiáng)制默認(rèn) | 結(jié)果為顯式 X | 結(jié)果為隱性 X | 結(jié)果為強(qiáng)制默認(rèn) | 結(jié)果為無(wú)排序規(guī)則 |
無(wú)排序規(guī)則 | 結(jié)果為顯式 X | 結(jié)果為無(wú)排序規(guī)則 | 結(jié)果為無(wú)排序規(guī)則 | 結(jié)果為無(wú)排序規(guī)則 |
運(yùn)算符和函數(shù)區(qū)分排序規(guī)則或不區(qū)分排序規(guī)則:
比較運(yùn)算符以及 MAX、MIN、BETWEEN、LIKE 和 IN 運(yùn)算符都區(qū)分排序規(guī)則。運(yùn)算符所使用的字符串被賦以具有較高優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。UNION 運(yùn)算符也區(qū)分排序規(guī)則,且所有的字符串操作數(shù)和最終結(jié)果被賦以具有最高優(yōu)先順序的操作數(shù)的排序規(guī)則。按列評(píng)估 UNION 操作數(shù)和結(jié)果的排序規(guī)則優(yōu)先順序。
賦值運(yùn)算符不區(qū)分排序規(guī)則,右邊的表達(dá)式投影到左邊的排序規(guī)則上。
字符串串聯(lián)運(yùn)算符不區(qū)分排序規(guī)則,兩個(gè)字符串操作數(shù)和結(jié)果被賦以具有最高排序規(guī)則優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。UNION ALL 和 CASE 運(yùn)算符不區(qū)分排序規(guī)則,所有的字符串操作數(shù)和最終結(jié)果都被賦以具有最高優(yōu)先順序的操作數(shù)的排序規(guī)則標(biāo)志。按列評(píng)估 UNION ALL 操作數(shù)和結(jié)果的排序規(guī)則優(yōu)先順序。
CAST、CONVERT 和 COLLATE 函數(shù)區(qū)分 char、varchar 和 text 數(shù)據(jù)類型的排序規(guī)則。如果 CAST 和 CONVERT 函數(shù)的輸入和輸出是字符串,則輸出字符串具有輸入字符串的排序規(guī)則標(biāo)志。如果輸入不是字符串,則輸出字符串為強(qiáng)制默認(rèn)并被賦以連接所使用的當(dāng)前數(shù)據(jù)庫(kù)的排序規(guī)則,或是包含引用 CAST 或 CONVERT 的用戶定義函數(shù)、存儲(chǔ)過(guò)程或觸發(fā)器的數(shù)據(jù)庫(kù)的排序規(guī)則。
對(duì)于返回字符串但不使用字符串輸入的內(nèi)置函數(shù),結(jié)果字符串為強(qiáng)制默認(rèn)并被賦以當(dāng)前數(shù)據(jù)庫(kù)的排序規(guī)則,或是包含引用該函數(shù)的用戶定義函數(shù)、存儲(chǔ)過(guò)程或觸發(fā)器的數(shù)據(jù)庫(kù)的排序規(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'
簡(jiǎn)單表達(dá)式 N'abc' 的 Unicode 數(shù)據(jù)類型具有較高的數(shù)據(jù)類型優(yōu)先順序,所以結(jié)果表達(dá)式將 Unicode 數(shù)據(jù)類型指派給 N'abc'。然而,表達(dá)式 CharCol 具有隱性排序規(guī)則標(biāo)志,而 N'abc' 具有較低的強(qiáng)制默認(rèn)排序規(guī)則標(biāo)志,所以使用的排序規(guī)則是 CharCol 的 French_CI_AS 排序規(guī)則。
相關(guān)文章