SQL Server 預設大小寫不敏感 (CI),導致 'admin' = 'ADMIN' 為真。密碼驗證、代碼比對、大小寫敏感業務鍵等場景需啟用大小寫敏感 (CS)。本文詳解 二進位轉換法與 排序規則指定法的語法、效能差異、適用範圍與最佳實務。
SELECT *
FROM T_User
WHERE CAST(UserName AS VARBINARY) = CAST('Admin' AS VARBINARY);
-- 1. 字串常數指定
WHERE Password COLLATE Latin1_General_CS_AS = 'Admin'
-- 2. 欄位指定 (若欄位預設 CI)
WHERE UserName = 'admin' AND Password COLLATE Chinese_PRC_CS_AS_WS = 'Admin'
-- 3. 資料庫/欄位永久變更 (需獨佔鎖)
ALTER TABLE T_User ALTER COLUMN Password NVARCHAR(50) COLLATE Latin1_General_CS_AS;
ALTER DATABASE MyDB COLLATE Latin1_General_CS_AS;
| 片段 | 含義 | 選項 |
|---|---|---|
| Chinese_PRC | 地區/字集:大陸簡體中文 Unicode 排序規則 | Latin1_General, Japanese_XJIS, Korean_Wansung, SQL_Latin1_General_CP1_CI_AS |
| CS / CI | Case Sensitive / Insensitive — 大小寫敏感/不敏感 | 核心開關 |
| AS / AI | Accent Sensitive / Insensitive — 重音敏感/不敏感 (法文 é vs e 等) | 歐洲語系關鍵 |
| KS / KI | Kana Sensitive / Insensitive — 平假名/片假名敏感/不敏感 | 日文專用 |
| WS / WI | Width Sensitive / Insensitive — 全形/半形敏感/不敏感 | 中日韓全形字元關鍵 |
| BIN / BIN2 | Binary — 純位元組比較,最快、最嚴格 | 效能最佳,但無語言感知 |
| 查詢寫法 | 執行計畫 | 耗時 | 索引使用 |
|---|---|---|---|
WHERE Password = 'Admin' (CI) | Index Seek | 1 ms | ✅ |
WHERE Password COLLATE Latin1_General_CS_AS = 'Admin' | Index Seek | 1 ms | ✅ (排序規則相容) |
WHERE CAST(Password AS VARBINARY) = CAST('Admin' AS VARBINARY) | Index Scan | 1,200 ms | ❌ 失效 |
關鍵發現: COLLATE 若與索引鍵排序規則相容 (同 CS/AS/WS),可保持 Index Seek;CAST VARBINARY 必然導致掃描。
CS_AS_WS (或 Latin1_General_100_CS_AS_SC),從根源解決。ALTER COLUMN ... COLLATE ..._CS_AS,僅影響該欄位,風險可控。COLLATE Latin1_General_CS_AS,保持 SARGable。CAST(... AS VARBINARY) 用於 WHERE 子句大表查詢。
-- 連結伺服器查詢,排序規則衝突
SELECT * FROM LocalDB.dbo.T1
JOIN LinkedSvr.RemoteDB.dbo.T2 ON T1.Code COLLATE Latin1_General_CS_AS = T2.Code;
-- 必須顯式指定一方排序規則,否則報錯 "Cannot resolve collation conflict"
掌握排序規則機制,能在不犧牲效能前提下,精準控制字串比較語意,是多語系、高安全系統的必修課。