因為英文算是Google大神的母語,為了能直接拿錯誤訊息向大神提問,達到"What you see, what you search!"的美妙境界,除了Office之外,我的OS、Server一直都裝英文版。

 (雖然這幾年下來,將中文錯誤訊息翻回英文的能力已經增強不少了,但直接用錯誤訊息查答案的爽快感受只有試過的人才知道,還很容易上癮!)

這個哲學逐步落實到我工作時的伺服器規劃上,只要沒有特別考量,我都會指定OS,SQL等要安裝英文版本。一直以來,這個策略是成功的,已有多次經驗靠著精準的錯誤訊息導引,快速地在Google中找到寶藏,克服了不少疑難雜症。不過,這幾天算第一次因為SQL轉換的語言版本踩到鐵釘"(未達踢到鐵板的程度,哈!)。

將原本中文版的mdf在英文版SQL Server Attach後,系統測試運作看來都正常,直到今天接到一個回報,出問題了。

原先開發的程式中有不少地方使用了類似以下的寫法(這不是良好的示範,稍後會解釋為什麼):

SELECT CONVERT(VARCHAR(10),GETDATE())
取得如"03 5 2007"的字串後,再拆字串取得日月年...

資料庫移到英文版後,情況就不太妙了,CONVERT的結果變成"Mar 5 200",不但出現了英文月份名,2007的最後一碼也因為長度不足而遺失。

請教了已歸隱山林的SQL大師--Ryan,原本誤以為SQL Server的日期格式是靠OS上的設定,這才發現SQL Server Instance Property上可以設Language,而英文版的預設語言是English,中文版則是Traditional Chinese,是此一設定影響了日期格式。SQL Server的Language設定依不同的登入帳號而有別,因此變更Server的語言不影響已建立帳號的Language,要從帳號的設定下手,以下整理一些與語言設定相關的指令操作。

要檢查目前登入帳號的語言設定,可以用
SELECT @@LANGUAGE

如果要在目前的Session中切換語言設定,可以用
SET LANGUAGE 'Traditional Chinese'

如果希望改變某個帳號的預設值,則可以由SQL Enterprise Manager(for 2000) /SQL Server Management Studio(for 2005)的帳號設定UI調整或是直接呼叫以下Stored Procedure:
sp_defaultlanguage 'sa', 'Traditional Chinese'

前述日期格式不如預期的狀況,將帳號的Language設成中文後就解決了。再回到先前CONVERT寫法的問題,誠如各位看到的,當CONVERT日期時未指定格式時,會由該帳號預設的Language決定格式,因此一旦其設定值有異,結果就會不同,但在這個案例中我們並不希望其格式因人而異,否則將影響之後的解析。因此,比較嚴謹的寫法應該要在CONVERT時指定格式(如果我們希望它的格式永遠都是dd mm yyyy),例如:
SELECT CONVERT(VARCHAR(10), GETDATE(), 106)

如此,即便是使用K隆星曆的Keroro執行這段Code,也會得到相同的結果,系統將可大幅減少出錯的機會。


Comments

# by 小熊子

以前常常發生過在於 DTS 的日期轉換上,接收文字檔轉入 Date 格式的欄位時, 會自動依登入帳號的語言自動解析,重新安裝不同語系 SQL Server 或者是 SQL Agent指定不同的執行身份後,就有可能會遇到。

Post a comment


97 - 64 =