「定序」到底是什麼?最簡單的來說,就是決定資料在資料庫裡排列的方式。聽起來好像也沒什麼大不了的,就只是排列的方式嘛… 對吧對吧?排列的方式可以有多重要?可以比吃飯重要嗎?只要結果資料可以秀出來,排列不對只是個小事而已,其實,我當初也是這樣想…
說到這裡,感覺好像還聽不出什麼重點。就讓我直說吧,當兩個 table 定序不同的時候如果有做 join 的動作,那就一定會發生「無法解析 equal to 作業中 xxx 與 ooo 之間的定序衝突」,因為 SQL Server 無法得知妳到底要遵從哪種定序,所以就直接給妳錯誤然後死在那裡,超級不負責任,跟我完全不一樣!
舉個例子,我們都知道 SQL 裡的 Order By 欄位,不過我們所謂的 Order By 欄位到底是 Order By 欄位裡的什麼呢?英文大小寫有差嗎?字體的全形半形有影響嗎?如果欄位裡面存的是中文資料,那是 Order By 筆劃嗎?還是發音?講了這麼多,「定序」(Collation)就是在做這件事。
如果在妳的 MS SQL Server Management Studio 上的 Database 上按滑鼠右鍵,妳可以在資料庫屬性裡的「一般」或是「擴充屬性」裡看到這個資料庫目前設定的「定序」是什麼。
妳目前所看到的是「Chinese_Taiwan_Stroke_BIN」,前面「Chinese_Taiwan」指的是語系,而後面 BIN 則是指「Binary」的意思,換句換說,就是表示目前是使用 Binary 來做排序,而也因為每個字的 binary 值不同,所以也可說是是這些資料欄位是有區分大小寫的。
再舉個例子「Chinese_Taiwan_Stroke_CI_AS」,「CI」是指 Case Insensitive(不區分大小寫),「AS」是指 Accent sensitivity(區分腔調),其他比較常見的還有「CS」Case sensitivity(區分大小寫)、「AI」Accent Insensitive(不區分腔調),「WS」Width sensitivity(區分全形半形)等等,其中還有比較特殊的「BOPOMOFO」可以讓妳不依照筆劃反而是依照中文 ㄅㄆㄇㄈ 發音來排序。
說了這麼多,相信妳應該有了個底,接下來就是整篇的重點了,萬一妳在 join 兩個定序不同的 table 而發生了譬如說「無法解析 equal to 作業中 "Chinese_Taiwan_Stroke_CI_AS" 與 "Chinese_Taiwan_Stroke_BIN" 之間的定序衝突」的問題,那該怎麼辦?這個可以區分為兩個主要解決辦法。
如果妳是開發人員角色,且在沒有辦法去修改後端資料庫時,最簡單的辦法就是在妳所 Join 的 table 後面直接加上 Collate 新定序名稱,這樣就解決了。例子如下
select EmpId, EmpName, CityName from Emp簡單吧!我就說,我也不懂為什麼外面的書籍或是教學文件為什麼要弄得那麼複雜。好吧,接下來就有一些些複雜了,如果妳是資料庫管理人員,而妳在無法更動程式的狀況下,想要直接一勞永逸修正資料庫來解決問題,就要照以下的步驟來做。
join City on Emp_CityId=CityId collate Chinese_Taiwan_Stroke_CI_AS
where EmpId='9F40460'
如果妳想要更改整個資料庫的定序,妳必須下以下的指令,因為在 MS SQL Management Studio 裡是不允許妳直接修改定序(避免妳操作不當選擇了錯誤的語系而把整個資料庫毀了)。
ALTER DATABASE 妳的資料庫名稱 SET SINGLE_USER WITH ROLLBACK IMMEDIATE第一行是鎖定目前資料庫給妳一個人使用,避免其他人更新,最後一行是恢復成多人使用,而第二行則是設定妳所想要的定序名稱。這個指令,不僅會直接更改資料庫的定序,連同這個資料庫下面的所有 tables 也都會被更改成這個新的定序,不過… 這邊就要聽好,重點來了,這個也僅只會更改「資料庫」與「Table」的定序,而 Table 下的欄位也有自己的定序,通常預設是跟 Table 一樣,不過有時候也有例外的情形…
ALTER DATABASE 妳的資料庫名稱 Collate Chinese_Taiwan_Stroke_CI_AS
ALTER DATABASE 妳的資料庫名稱 SET MULTI_USER WITH ROLLBACK IMMEDIATE
如果以上的指令下過了,妳還是發生同樣的定序錯誤,那妳就得看一下 SQL 語法到底是哪個欄位與欄位之間做 join 時定序發生錯誤,而直接去修改那個欄位的定序。
修改欄位的定序可以在 MS SQL Management Studio 上直接設定。
可以指定或或是使用目前 Table 的預設值(還原預設值)。
不過… 天底下有時候就是這麼剛好有這麼衰的事,當妳無從得知程式背後是如何運作的同時,又剛好發生定序錯誤… 唯一的辦法,就是一個 table、一個 table、一個欄位、一個欄位的掃一遍了… 而這種好死不死的衰事,最近這幾天就剛好發生在我身上… 唉…(要不然也不會有這麼枯燥的這篇出現了)
13 回應:
嗯....
閱))只針對中文字有沒有錯字而已!!
(飄過)))))
等一下,我抓到一個錯字!
資料褲!!除非你這個一堆堆的東西是要穿褲子的,不然這個應該是錯字...
修正修正!
玉姐您老慢走啊~
啊~~~~~
原來如此 !!
希望我可以解決我的問題 !!
終於找到了如何修改db定序的方法,
感激不盡 ^0^
這種好用的文章應該多一點才是
看... 看不懂 ~>_<~
如果欄位定序錯亂,那還真的是超慘的...
我也是苦主之一啊,真的無解 ><
謝謝你的生日祝福!我真喜歡你!
雖然你老是寫一些我根本看不懂的文章,我還是喜歡你!
別忘了222喔。
感謝您的文章,讓我解決了問題....
thank you ^^
水啦...清楚無比,謝啦~
讚讚讚~
簡單明瞭 清楚易懂!
感恩大大
祝福您~
張貼留言