本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
定序限制與行為差異
Babelfish 使用 ICU 程式庫來支援定序。PostgreSQL 以特定版本的 ICU 建置,最多只能符合定序的一個版本。不同版本的變化不可避免,就像語言隨著時間演變,也會發生微小的變化。您下列清單中可以找到 Babelfish 定序的已知限制和行為變化:
索引與定序類型相依性 – 依據 International Components for Unicode (ICU) 定序程式庫 (Babelfish 使用的程式庫) 的使用者定義類型索引,不會在程式庫版本變更時失效。
COLLATIONPROPERTY 函數 – 針對支援的 Babelfish BBF 定序實作定序屬性。如需詳細資訊,請參閱 Babelfish supported collations table。
Unicode 排序規則差異 – SQL Server 的 SQL 定序將 Unicode 編碼的資料 (
nchar
和nvarchar
) 排序的方式不同於非 Unicode 編碼的資料 (char
和varchar
)。Babelfish 資料庫一律為 UTF-8 編碼,且不論資料類型為何,一律以一致的方式套用 Unicode 排序規則,因此char
或varchar
的排序順序與nchar
或nvarchar
的相同。-
第二級相等定序與排序行為 – 預設 ICU Unicode 第二級相等 (
CI_AS
) 定序將標點符號和其他非英數字元排在數值字元前面,並將數值字元排在字母字元前面。但是,標點符號和其他特殊字元的順序不同。 -
Tertiary collations, workaround for ORDER BY – SQL 定序 (例如
SQL_Latin1_General_Pref_CP1_CI_AS
) 支援TERTIARY_WEIGHTS
函數,且能夠將CI_AS
定序中視為同等的字串排序為大寫優先:ABC
、ABc
、AbC
、Abc
、aBC
、aBc
、abC
,最後是abc
。因此,DENSE_RANK OVER (ORDER BY column)
分析函數將這些字串評估為相同等級,但在分割區內以大寫優先來排序。在 Babelfish 中,您可以在指定第三級
CS_AS
定序的ORDER BY
子句中,新增COLLATE
子句來指定@colCaseFirst=upper
,以獲得類似的結果。不過,colCaseFirst
修飾詞僅適用於第三級相等的字串 (而不是第二級相等,例如CI_AS
定序)。因此,您無法使用單一 ICU 定序來模擬第三級 SQL 定序。為了解決這種情況,建議您將使用
SQL_Latin1_General_Pref_CP1_CI_AS
定序的應用程式修改成優先使用BBF_SQL_Latin1_General_CP1_CI_AS
定序。然後將COLLATE BBF_SQL_Latin1_General_Pref_CP1_CS_AS
新增至此資料欄的任何ORDER BY
子句。 -
字元擴充 – 字元擴充將單一字元視為等同於主要層級的一連串字元。SQL Server 的預設
CI_AS
定序支援字元擴展。ICU 定序僅支援不區分重音定序的字元擴展。需要字元擴充時,請使用
AI
定序來做比較。不過,LIKE 運算子目前不支援這種定序。 -
char 與 varchar 編碼 – 當 SQL 定序用於
char
或varchar
資料類型時,ASCII 127 之前的字元由該 SQL 定序的特定字碼頁決定排序順序。使用 SQL 定序時,宣告為char
或varchar
的字串與宣告為nchar
或nvarchar
的字串,可能以不同方式排序。PostgreSQL 使用資料庫編碼將所有字串編碼,因此會將所有字元轉換為 UTF-8,並根據 Unicode 規則來排序。
因為 SQL 定序使用 Unicode 規則來排序 nchar 和 nvarchar 資料類型,所以 Babelfish 使用 UTF-8 將伺服器上的所有字串編碼。Babelfish 使用 Unicode 規則來排序 nchar 和 nvarchar 字串的方式,同於排序 char 和 varchar。
-
補增字元 – SQL Server 函數
NCHAR
、UNICODE
及LEN
支援 Unicode Basic Multilingual Plane (BMP) 以外字碼指標的字元。反之,非 SC 定序使用代理配對字元來處理增補字元。對於 Unicode 資料類型,SQL Server 可以使用 UCS-2 來表示最多 65,535 個字元,或者,如果使用增補字元,則表示完整的 Unicode 範圍 (1,114,114 個字元)。 -
區分假名 (KS) 定序 –「區分假名」(KS) 定序會將
Hiragana
和Katakana
日文假名字元視為不同。ICU 支援日文定序標準JIS X 4061
。現在已棄用的colhiraganaQ [on | off]
地區設定修飾詞可能有同於 KS 定序的功能。不過,Babelfish 目前不支援與 SQL Server 同名的 KS 定序。 -
區分寬度 (WS) 定序 – 將單一位元組字元 (半形) 和以雙位元組字元 (全形) 表示的同一個字元視為不同時,定序就稱為區分寬度 (WS)。不過,Babelfish 目前不支援與 SQL Server 同名的 WS 定序。
-
區分變化選擇器 (VSS) 定序 – 區分變化選擇器 (VSS) 定序會區分日文定序
Japanese_Bushu_Kakusu_140
和Japanese_XJIS_140
中的表意變化選擇器。變化序列由一個基本字元加上一個額外的變化選擇器組成。如果您未選取_VSS
選項,則做比較時不會考慮變化選擇器。Babelfish 目前不支援 VSS 定序。
-
BIN 與 BIN2 定序 – BIN2 定序根據字碼指標順序來排序字元。UTF-8 的逐位元組二進制順序保留 Unicode 字碼指標順序,因此這也可能是表現最佳的定序。如果 Unicode 代碼指標順序適用於應用程式,請考慮使用 BIN2 定序。不過,使用 BIN2 定序可能會導致資料在用戶端以超出文化預期的順序顯示。隨著時間經過,Unicode 中也增加對小寫字元的新映射,因此
LOWER
函數在不同版本的 ICU 上可能有以不同方式運作。這是較常見定序版本控制問題的特殊情況,而不是 BIN2 定序所獨有。Babelfish 隨著 Babelfish 發佈而提供
BBF_Latin1_General_BIN2
定序,以依照 Unicode 代碼指標順序來排序。在 BIN 定序中,只有第一個字元排序為 wchar。剩餘的字元逐位元組來排序,實際上是依照符合其編碼的代碼指標順序。這種作法未遵循 Unicode 定序,Babelfish 並不支援。 非確定性定序和 CHARINDEX 限制 – 對於早於第 2.1.0 版的 Babelfish 版本,您無法將 CHARINDEX 與非確定性定序搭配使用。預設情況下,Babelfish 使用不區分大小寫 (非確定性) 定序。對舊版 Babelfish 使用 CHARINDEX 會造成下列執行時間錯誤:
nondeterministic collations are not supported for substring searches
注意
此限制和解決方法僅適用於 Babelfish 1.x 版 (Aurora PostgreSQL 13.x 版)。Babelfish 2.1.0 及更新版本沒有此問題。
您可以透過以下其中一種方法解決此問題:
將表達式明確轉換為區分大小寫的定序,並套用 LOUP 或 UPER 將這兩個參數進行大小寫折疊 (case-fold)。例如,
SELECT charindex('x', a) FROM t1
會變成下列:SELECT charindex(LOWER('x'), LOWER(a COLLATE sql_latin1_general_cp1_cs_as)) FROM t1
建立一個 SQL 函數 f_charindex,並將 CHARINDEX 呼叫替換為對以下函數的呼叫:
CREATE function f_charindex(@s1 varchar(max), @s2 varchar(max)) RETURNS int AS BEGIN declare @i int = 1 WHILE len(@s2) >= len(@s1) BEGIN if LOWER(@s1) = LOWER(substring(@s2,1,len(@s1))) return @i set @i += 1 set @s2 = substring(@s2,2,999999999) END return 0 END go