SQL Server 預設排序規則與具有不同排序規則的數據庫 - 潛在問題?
我正在努力設計必須使用與 SQL Server 實例預設排序規則(X 排序規則)不同的排序規則(Y 排序規則)的新數據庫。我正在尋找潛在的問題。
預設情況下,臨時表將使用 X 排序規則創建,因此除非我在列上創建帶有 Y 排序規則的臨時表,否則文本數據類型的任何連接都將失敗。
SQL Server 字元串函式:
REPLACE
、SUBSTRING
等呢?它們總是以 X 排序規則返回嗎?我用的時候REPLACE(...) COLLATE Y
呢?您是否看到任何潛在的數據失去或任何不同的問題?
…新數據庫必須與 SQL Server 實例預設排序規則(X 排序規則)不同的排序規則(Y 排序規則)。
為什麼新數據庫需要採用不同的排序規則?
預設情況下,臨時表將使用 X 排序規則創建,因此除非我在 cols 上創建帶有 Y 排序規則的臨時表,否則文本數據類型的任何連接都將失敗。
正確的。儘管您不需要使用
COLLATE DATABASE_DEFAULT
,但在某些情況下可能完全不正確/不好。要求是 A) 排序規則對於連接的字元串列是相同的,或者用於連接/UNION 等,或者 B) 您COLLATE
在謂詞或表達式中指定子句以覆蓋一個或多個列。意思是,如果您知道您的列的排序規則為 Z,並且您的數據庫的預設排序規則為 Y,則創建為該
COLLATE Z
列指定的臨時表。請記住,表變數使用數據庫的預設排序規則,而不是實例的排序規則。而且,包含的數據庫是另一套規則。SQL Server 字元串函式:
REPLACE
、SUBSTRING
等呢?它們總是以 X 排序規則返回嗎?內置函式通常在數據庫的預設排序規則中返回一個字元串,除非您使用該
COLLATE
子句傳入列或表達式。您是否看到任何潛在的數據失去?
這取決於您使用的數據類型以及您使用的排序規則。
NVARCHAR
///以大寫“N”為前綴的文字僅適用於 UnicodeNCHAR
(NTEXT
UTF-16),因此如果在這些上切換排序規則,則不會失去潛在的數據。VARCHAR
///不以大寫“N”為前綴的字面量CHAR
是8 位編碼,具體的編碼由與所使用的排序規則的程式碼頁關聯決定。這裡有潛在的數據失去*,如果*TEXT
將排序規則切換到使用不同程式碼頁的排序規則。但即使這樣也不能保證數據失去,因為只有當數據中存在新程式碼頁中不可用的字元時才會發生數據失去。(從技術上講,在混合單字節字元集、雙字節字元集、UTF-8 和 UTF-16 的各種組合時,您也可能會遇到數據失去,這取決於您要進入的方向,但這不是問題大多數人都會遇到——儘管隨著越來越多的人開始使用從 SQL Server 2019 開始的新的 UTF-8 排序規則,更多的人可能會遇到)或者可能有任何不同的問題?
請記住:
- 實例級排序規則控制:
變數名/游標名/
GOTO
標籤解析。數據庫級排序規則是什麼並不重要。實例級元數據:登錄名、伺服器名、伺服器角色名、伺服器級對象、數據庫名等。
預設排序規則:
- 新創建的數據庫(除非
CREATE DATABASE
語句包含該COLLATE
子句)tempdb
元數據(臨時對象/約束/索引/預設值/永久表/等的名稱)- 臨時表和永久表中的列
tempdb
- 數據庫級排序規則控制:
數據庫級元數據:使用者名、模式名、數據庫角色名、模式綁定對象名等。
預設排序規則:
- 表變數、永久表、TVF 結果中的列
字元串文字
字元串變數(變數的內容,而不是名稱)
標量 UDF 的返回值
有關排序規則在各個級別的作用以及更改它們時要注意的事項的更詳盡列表,請參閱我的以下文章: