因為偶然的原因,需要在INNER JOIN聯表時,讓對應欄位進行區分大小寫的比較。而預設情況下建立的Sql Server資料庫是不區分大小寫,這個需求怎麼實現呢?
要實現這個需求,至少有三個操作層級來實現:
1. 資料庫層級:整個資料庫中的char、varchar、text、nchar、nvarchar 和 ntext 資料都區分大小寫。(為描述方便,下文不再明確強調這些資料類型。)但這樣做有個明顯的壞處,那就是整個資料庫的這些欄位的比較,都要進行嚴格匹配。比如下面的兩條Sql語句會得到完全不同的兩種結果:
SELECT * FROM [TABLE] WHERE [COLUMN] LIKE ‘%KeyWord%’SELECT * FROM [TABLE] WHERE [COLUMN] LIKE ‘%keyword%’
因為資料庫在比較時會嚴格按照大小寫來區別,這樣就會導致我們在程式開發過程中難以滿足十分複雜的查詢需求,特別突出的例子便是關鍵字搜尋——我們無法預知客戶輸入內容的大小寫,我們更不能要求客戶輸入的關鍵字區分大小寫。
2. 表欄位層級:只對特定的表欄位進行大小寫區分。這樣做在整體上減小了大小寫限定的範圍,從全資料庫減小到當前指定的欄位。但使用起來仍然有些局限性。
3. 查詢層級:只對本次查詢限定大小寫區分。這也是本文重點介紹的實現方式。這樣操作可以讓我們不對以前的資料庫做任何的修改,只對當前這次查詢區分大小寫,也不會影響程式中別處對這些欄位的查詢。
好了,上文說了三個實現層級,那具體怎麼實現呢?這就要用到SQL資料庫中的“定序”了。我們可以在資料庫的屬性上,設定定序,也可以在表設計的欄位屬性裡設定定序。具體要設定什麼樣的定序,後面來說,我們先說查詢層級的定序。下面有一段SQL片段可以示範在查詢層級區分大小寫定序應用:
use tempdbset nocount on--1--print '建立初始資料表Customer'create table Customer(id int,uname varchar(10))insert into Customer select 1,'Jim' union allselect 2,'Simith' union allselect 3,'uonun'select * from Customer--2--print '建立初始資料表Info'create table Info(uname varchar(10),phone varchar(11))insert into Info select 'JIM','13800000000' union allselect 'Simith','13911111111' union allselect 'uonun','13812345678'select * from Info--3--print '不區分大小寫,不區分全半形'select c.id,c.uname as 'c.uname',i.uname as 'i.uname',i.phonefrom Customer as c inner join Info as ion c.uname = i.uname--4--print '區分大小寫,不區分全半形'select c.id,c.uname as 'c.uname',i.uname as 'i.uname',i.phonefrom Customer as c inner join Info as ion c.uname = i.unamecollate Chinese_PRC_CS_AS--5--print '不區分大小寫,區分全半形'select c.id,c.uname as 'c.uname',i.uname as 'i.uname',i.phonefrom Customer as c inner join Info as ion c.uname = i.unamecollate Chinese_PRC_CI_AI_WS--6--print '區分大小寫,區分全半形'select c.id,c.uname as 'c.uname',i.uname as 'i.uname',i.phonefrom Customer as c inner join Info as ion c.uname = i.unamecollate Chinese_PRC_CS_AI_WSDROP TABLE CustomerDROP TABLE Info/*建立初始資料表Customerid uname----------- ----------1 Jim2 Simith3 uonun建立初始資料表Infouname phone---------- -----------JIM 13800000000Simith 13911111111uonun 13812345678不區分大小寫,不區分全半形id c.uname i.uname phone----------- ---------- ---------- -----------1 Jim JIM 138000000002 Simith Simith 139111111113 uonun uonun 13812345678區分大小寫,不區分全半形id c.uname i.uname phone----------- ---------- ---------- -----------2 Simith Simith 139111111113 uonun uonun 13812345678不區分大小寫,區分全半形id c.uname i.uname phone----------- ---------- ---------- -----------1 Jim JIM 138000000003 uonun uonun 13812345678區分大小寫,區分全半形id c.uname i.uname phone----------- ---------- ---------- -----------3 uonun uonun 13812345678*/
通過上面的SQL語句可以看出,我們在查詢時使用COLLATE字句,指定定序可以影響查詢結果。通過上面的圖也可以看出,這個定序除可以區分大小寫之外,還可以區分重音、假名、全半形。
結束語:
- 本文沒有更深入研究定序的其他應用,比如對Order by的影響。
- 本文沒有更深入研究在查詢時對多個不同欄位的影響機制。
- 範例程式碼另見CorePlex程式碼程式庫: http://udnz.com/Code-409.htm
參考《SQL Server 2008 聯機叢書》:
使用定序:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-CHS/s10de_1devconc/html/61cdbb6b-3ca1-4d73-938b-22e4f06f75ea.htm
COLLATE:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-CHS/s10de_6tsql/html/76763ac8-3e0d-4bbb-aa53-f5e7da021daa.htm