校勘(collation)是指對代碼頁、字母大小寫、音調、語言和字母表的整理,很多校勘都是在數據進入數據庫之前進行的,根據我的經驗,北美的大部分數據庫管理員都在使用默認的大小寫敏感的校勘設定,這對于數據本身沒有影響,但是對于數據的比較和索引會造成影響。
這篇文章將向您介紹一些相關的校勘方法,以及數據庫對多種字符集的處理方法。
為了說明校勘的使用,我們首先來創建一個數據庫,列表A給出了創建數據庫的代碼。
CREATE SCHEMA CaseCheck
GO
CREATE TABLE CaseCheck.Names
(
NamePK Int Identity(1,1) PRIMARY KEY,
Name Varchar(50) NOT NULL
)
GO
INSERT INTO CaseCheck.Names VALUES (''Fuller'')
INSERT INTO CaseCheck.Names VALUES (''FuLLer'')
INSERT INTO CaseCheck.Names VALUES (''FULLER'')
INSERT INTO CaseCheck.Names VALUES (''fuller'')
GO
列表A
列表B是一些查詢,對于大小寫不敏感的情況,這幾個查詢將返回相同的四個數據行,但是如果我們的任務是從數據行中選取大小寫完全匹配的記錄呢?
SELECT * FROM CaseCheck.Names
SELECT * FROM CaseCheck.Names WHERE Name = ''fuller''
SELECT * FROM CaseCheck.Names WHERE Name = ''FULLER''
SELECT * FROM CaseCheck.Names WHERE Name = ''fuller''
GO
列表 B
現在我們就要使用校勘的功能了,盡管在數據庫創建的時候,數據庫管理員已經指定了校勘的選項,但是您可以通過WHERE語句中的COLLATE選項來使用不同的校勘設定,在列表C的查詢中,前三個都返回了一條記錄,而最后一個查詢的返回結果為空。
SELECT * FROM CaseCheck.Names WHERE Name = ''fuller''
COLLATE Latin1_General_CS_AS
SELECT * FROM CaseCheck.Names WHERE Name = ''FULLER''
COLLATE Latin1_General_CS_AS
SELECT * FROM CaseCheck.Names WHERE Name = ''fuller''
COLLATE Latin1_General_CS_AS
SELECT * FROM CaseCheck.Names WHERE Name = ''FUllER''
COLLATE Latin1_General_CS_AS
GO
列表 C
假設您現在想把所有''fuller''形式的拼寫改為''Fuller''(包括像''fUlLEr''這種毫無意義的拼寫組合),通過列表D中的代碼,您可以非常輕松地實現這一功能。
UPDATE CaseCheck.NamesSET Name = UPPER(LEFT(Name,1))
+ LOWER(SUBSTRING(Name,2,LEN(Name)-1))
列表D
從大型主機上導入數據的時候,我都會首先運行以上的代碼,這樣就不必再擔心單詞大小寫的問題了。
如果您想查看所有的校勘選項及其簡要說明,可以運行以下的SQL代碼:SELECT * FROM ::fn_helpcollations()。
想要查看數據庫當前的校勘設定,可以使用以下代碼:
SELECT collation_name
FROM master.sys.databases
WHERE Name=''SQLTips''
在列表E中,我添加了一些帶有特殊字符的數據行,我使用了我的好朋友DejanSunderic的名字,他的名字應該拼寫為?underic''(字母c實際上應該有重音符號的,由于使用的字體,所以顯示成了現在的效果)。
INSERT INTO CaseCheck.Names VALUES
(NChar(352)+ ''underi'' + NChar(263))
INSERT INTO CaseCheck.Names VALUES
(''SUNDERIC'')
INSERT INTO CaseCheck.Names VALUES
(''sUnDeRI'' + Nchar(263))
INSERT INTO CaseCheck.Names VALUES
(''Sunderi'' + Nchar(263))
GO
列表 E
如果不使用COLLATE,那么會發生非常有意思的事情,運行一下的查詢語句:
SELECT *
FROM CaseCheck.Names
WHERE Name LIKE N''S%''
您得到的結果是:
NamePK Name
6 SUNDERIC
7 sUnDeRIc
8 Sunderic
注意,帶有特殊字符的''?underic''并沒有被包含在內,
讓我們再來看看另外一個實驗:
SELECT * FROM CaseCheck.Names
ORDER BY Name
運行此查詢的結果如下:
NamePK Name
5 ?underic
1 Fuller
2 FuLLer
3 FULLER
4 fuller
6 SUNDERI
7 sUnDeRIc
這里有很明顯的錯誤,PK5應當位于''Fuller''之后,我不是語言專家,因此不知道它應該位于Ss的什么位置,但是我覺得這是本地規則造成的結果,很明顯,''?underic''應該出現在所有的''Fuller''之后,而不是在''Fuller''前面。
我還進行了另外一項實驗,使用西里爾字母來拼寫我的好朋友Alexander Karmanov的名字,在圖片A中您可以看到西里爾字母的拼寫,我運行了圖片B所示的語句來添加這條記錄。
圖片A

圖片B

圖片C
使用默認的字符集,此查詢將會返回一系列問號,如果您想得到正確的結果,那么必須需要使用數據庫可以接受的Unicode字符集,參見圖片C。
如果您想確認一個給定數據庫中使用的初始校勘,可以使以下的代碼:
SELECT collation_name
FROM master.sys.databases
WHERE Name = "SQLTips"