SQL Server作為一個(gè)國際化產(chǎn)品,支持多語(yǔ)言環(huán)境。在SQL Server中,字符集被稱(chēng)為排序規則(即Collation)。排序規則不僅影響記錄行的sort順序,還影響中文顯示是否亂碼等。在SQL Server中,排序規則可在3處地方設置:
服務(wù)器級別 =>instances
db庫級別 =>databases
表列級別 =>columns
上圖所示為SQL Server默認情況下對Collation繼承的方式。
即在SQL Server軟件安裝時(shí)我們可設置服務(wù)器級別的排序規則,也就是instances的排序規則。如下所示是使用T-SQL查詢(xún)當前instances的排序規則信息:
--查詢(xún)當前SQL Server服務(wù)器的排序規則SELECT SERVERPROPERTY(N'Collation')--------------------------------------------------Chinese_PRC_CI_AS當然你也可以使用SSMS查看服務(wù)器屬性:
若在創(chuàng )建databases時(shí)我們未指定排序規則,databases則會(huì )使用instances的排序規則。如下所示是通過(guò)sql代碼查詢(xún)或修改SQL Server中databases的排序規則信息:
--在創(chuàng )建database時(shí)指定排序規則:SQL_Latin1_General_CP1_CI_ASUSE master;GOCREATE DATABASE mydbCOLLATE SQL_Latin1_General_CP1_CI_ASGO--通過(guò)目錄視圖sys.databases查詢(xún)databases的排序規則SELECT name, collation_nameFROM sys.databasesWHERE name = N'mydb';-------------------------------------------------mydb SQL_Latin1_General_CP1_CI_AS--修改現有databases的排序規則ALTER DATABASE mydbCOLLATE Chinese_PRC_CI_AS而表中的列(columns)默認情況是繼承databases的排序規則(除非在創(chuàng )建表時(shí)對列的排序規則進(jìn)行指定),我們可通過(guò)目錄視圖sys.columns查詢(xún)表中columns的排序規則信息。
這里需注意:SQL Server的排序規則只影響字符型的列,如char, varchar, text, nchar, nvarchar, ntext,因此目錄視圖sys.columns中非字符型的排序規則顯示為NULL
--注意:只有字符型的列才會(huì )顯示排序規則信息,非字符型的顯示為NULLSELECT name, collation_nameFROM sys.columnswhere collation_name is NOT NULL在安裝SQL Server時(shí),你可能困惑應該選擇哪種字符集,SQL Server或者Windows的。官方推薦使用SQL Server的字符集,而非Windows的字符集。原因是,SQL Server字符集是基于Windows衍生出來(lái)的,同時(shí)保證SQL Server版本間的兼容性, 如SQL Server 2014可使用的字符集比2008多
--查看當前SQL Server支持的排序規則SELECT * from ::fn_helpcollations()注意字符集的名字縮寫(xiě)與對應的的描述,如CI表示不區分大小寫(xiě)、
我們不難理解:只需保持SQL Server中3處字符集設置的地方:instances、databases、columns設置一致即是正確的使用方式。
那么當SQL Server中instances與databases對排序規則設置不一致時(shí),將直接導致臨時(shí)表#或##不能正常使用(臨時(shí)表的列默認繼承tempdb的排序規則,而tempdb則繼承了instances的排序規則)。
/*注意: 這里mydb的字符集是SQL_Latin1_General_CP1_CI_AS, 而instance的字符集是Chinese_PRC_CI_AS*/USE mydb;GO--在mydb中創(chuàng )建一張表collation_testCREATE TABLE collation_test (hyper varchar(10));GO--創(chuàng )建臨時(shí)表collation_tempCREATE TABLE #collation_temp (hyper varchar(10));GO連接查詢(xún)上述臨時(shí)表的內容時(shí),將出現如下報錯信息:
--查詢(xún)報錯SELECT *FROM collation_test lLEFT JOIN #collation_temp c ON l.hyper = c.hyper;--------------------------------------------Msg 468, Level 16, State 9, Line 4無(wú)法解決 equal to 運算中 "Chinese_PRC_CI_AS" 和 "SQL_Latin1_General_CP1_CI_AS" 之間的排序規則沖突。其根本原因是由于表collation_test與臨時(shí)表#collation_temp中列的排序規則不一致。雖然可以通過(guò)以下2種方式繼續使用臨時(shí)表,但并不推薦。如下通過(guò)指定select表中列的排序規則,繼續使用上述兩張表。
--方式1:--注意指定表collation_test使用排序規則COLLATE Chinese_PRC_CI_ASSELECT *FROM collation_test l LEFT JOIN #collation_temp c ON l.hyper COLLATE Chinese_PRC_CI_AS = c.hyper------------------------------------------------------- 第二種解決方法則是在創(chuàng )建表時(shí)指定列的排序規則
--方式2USE mydb;GO--注意指定了列的排序規則:COLLATE Chinese_PRC_CI_ASCREATE TABLE collation_Wang(hyper varchar(10) COLLATE Chinese_PRC_CI_AS);--保持列的排序規則一致即可正常使用臨時(shí)表#collation_tempSELECT *FROM collation_wang wLEFT JOIN #collation_temp c ON w.hyper = c.hyper-------------------------------------------------------同時(shí)instances的排序規則設置會(huì )影響SQL Server數據的導入導出功能。
通常我們遇到的另一個(gè)問(wèn)題是:通過(guò)SSMS(即SQL Server Management Studio)插入(insert)的中文,在查詢(xún)時(shí)顯示亂碼(即問(wèn)號?)。
--在上述表collation_test插入中文INSERT INTO collation_test VALUES ('東') --查詢(xún)表collation_test的記錄select * from collation_test查詢(xún)顯示亂碼:
這當然是由于表collation_test上hyper列的字符集設置不正確所導致的。但若你有幸在表上使用了nvarchar等類(lèi)型,那么當出現上述亂碼時(shí),也許你還可以使用如下臨時(shí)方式補救:
/* 注意: 數據庫mydb依舊是使用錯誤的排序規則:SQL_Latin1_General_CP1_CI_AS, 但是表collation_nvarchar使用了nvarchar類(lèi)型,而非varchar */USE mydb;GOCREATE TABLE collation_nvarchar (hyper nvarchar(10));GO--臨時(shí)處理方式INSERT INTO collation_nvarchar VALUES (N'東'); --錯誤插入方式INSERT INTO collation_nvarchar VALUES ('東'); --查詢(xún)表collation_nvarchar的記錄select * from collation_nvarchar綜上述,我們應盡可能的正確設置SQL Server排序規則:
1. 正確的設置SQL Server排序規則 ,保持instances、databases、columns中3處排序規則一致,推薦使用Chinese_PRC_CI_AS
2. 盡可能使用nvarchar等Unicode類(lèi)型,而非varchar類(lèi)型
Setting and Changing the Database Collation
https://msdn.microsoft.com/en-us/library/ms175835(v=sql.105).aspx
sys.columns (Transact-SQL)
https://msdn.microsoft.com/en-us/library/ms176106(v=sql.120).aspx
Collation and International Terminology
https://msdn.microsoft.com/en-us/library/ms143726(v=sql.105).aspx
聯(lián)系客服