定序問題
情境1
當 Join 查詢兩個以上不同的資料庫,其定序不一致時就會發生以下錯誤:
無法解析 equal to 作業中 "Chinese_Taiwan_Stroke_BIN" 與 "Chinese_Taiwan_Stroke_CI_AS" 之間的定序衝突
解法:
SELECT *
FROM DB1.dbo.table1 A, DB2.dbo.table2 B
WHERE A.PK1 = (B.PK1 COLLATE Chinese_Taiwan_Stroke_BIN)
情境2
假設 Customers 資料表格裡有 city 欄位,裡面包含了台灣各縣市,當我們 SELECT 這個表格,下了 ORDER BY city 時:
回傳的結果裡台北排在前面,彰化的彰因為筆劃最多所以排最後 => 因為 SQL Server 在台灣地區的預設定序是 Chinese_Taiwan_Stroke_CI_AS
情境3
找出特定 TABLE 裡欄位屬性,有指定定序
SELECT * ,table_name,column_name as '欄位名' , column_default as '默認值'
FROM information_schema.columns
WHERE 1=1
AND table_name = 'LicenseMaster' --指定 Table Name
AND TABLE_SCHEMA ='license' --指定 Table Owner
AND COLLATION_NAME is not null
如果想用其他的排序法,ex. 注音,可以下:
SELECT customerid, city FROM dbo.Customers
ORDER BY city COLLATE Chinese_Taiwan_BOPOMOFO_CI_AI
Chinese_Taiwan_BOPOMOFO_CI_AI 代表按照注音排序
什麼是定序?
決定資料庫所使用的字元集、排序的方式
以上述情境1來說,當兩張 table 的 PK1 欄位定序不同時,他會**不知道要怎麼做 join**,所以會報錯
以上述情境2來說,要 order by city 欄位,就是依照此欄位的定序來決定要怎麼排
定序名稱的每一個部份都有其意義
以 [Chinese_Taiwan_Stroke]_CS_AS_WS 來說:
- [SortRules] 用來識別指定字典排序時套用排序規則之字母或語言的字串。例如 Latin1_General 或 Chinese_Taiwan_Stroke
- Case Sensitivity: CI 指定不區分大小寫,CS 指定區分大小寫
- Accent Sensitivity: AI 指定不區分腔調字,AS 指定區分腔調字 (通常用在歐洲語系,如法文)
- Kana Sensitivity: KS 指定區分假名 (用在日文)
- Width Sensitivity: WS 指定區分全半形,不寫就表示不區分
BIN 指定要用的二進位排序順序,通常是區分大小寫、全半形
例如: _CS_AS_WS => 區分大小寫、區分腔調字、區分全半形
SQL Server 要怎麼查看定序?
定序有分為3種層級: 伺服器等級、資料庫等級、資料行等級
- 查看**伺服器**等級定序:
SELECT CONVERT(varchar(256), SERVERPROPERTY('collation'));
- 查看**資料庫**等級定序:
SELECT name, collation_name FROM sys.databases;
- 查看**資料行**等級定序: (因下指令的結果會有很多筆,可能造成混淆,所以在此提供使用 SQL 工具的方式)
- step1. 在要查看的資料表點擊右鍵 -> 設計
- step2. 點擊想看的欄位,下面的屬性就可看到定序
用語法調整欄位屬性後面要補上定序,不然會變回 DB 預設定序,例如:
ALTER TABLE [dbo].[table]
ALTER COLUMN [FormNo] nvarchar(80) COLLATE Chinese_Taiwan_Stroke_CI_AS;