這週有個客戶的案子幾百隻程式上線,上線後的隔天早上,同事S回報了系統程式出現很基本的SQL語法錯誤,明明年輕的工程師都測試過,還是發生了。
為了要掩蓋自己對這次問題原因的了解不足(是相容性層級嗎?),趕緊掛上電話花幾分鐘簡單的測試,試試改相容性層級然後回報同事S,最後發現問題在於不同SQL版本對全形空白的解析有差異,這次和相容性層級無關,晚上看F1賽車不練跑,快來筆記這個全形空白問題。
好,我們來簡單測試作筆記。
使用中的版本測試
先建立預存程序usp_testfullwidthspace
CREATE proc usp_testfullwidthspace
as
SELECT @@version
SELECT * FROM sys.assemblies
WHERE name LIKE '%sql%'
執行測試
exec usp_testwidespace
SQL Server 2012 : 正常!
SQL Server 2014: 正常!
SQL Server 2016: 正常!
SQL Server 2008 執行: 建立預存程序時就會出現語法不正確!
原來中間多了一個全形空白(Unicode編碼是U+3000)
問題原因
好,結果就是T-SQL程式中夾帶了全型空白(Unicode編碼3000)在SQL Server 2012之後都視為正常了,2008R2不行。
至於為何這樣?從微軟connect找到一篇日本網友Nagino的提問,最後問題有收到SQL Server PM的回覆,原來SQL Server 在2012之後將U+3000視為fullwidth (全形空白),但在SQL 2008R2還沒開始防範。
切換全半形
是人都有機會出錯,猜測年輕的工程師可能切換鍵盤輸入法時,切到了全形。
切換回來的方式:
- 熱鍵切換全半形: Shift + Space
- 或滑鼠滑到輸入法按下右鍵
小結
1.在這個案子中,除了業務需求,客戶也希望夾帶DB升級的需求,預計從SQL Server 2008 R2升級到SQL 2014,測試環境設定的版本是SQL2014。
2.案子到了中期後,客戶又希望拆出部分的AP提前在DB升級前上線,這週先上AP,但因為正式環境還是SQL 2008,最後一次建置測試資料庫環境時,還特地取消了要提升資料庫的相容性層級從100到120的步驟,所以像是2012多的TRY_CAST、TRY_CONVERT、TRY_PARSE函數也可以避免掉先上線使用。。
但環境差異的風險還是發生了,以後升級checklist加一條。
3.其實比較喜歡SQL2016,應該一口氣升到2016,而且2016也出sp1了,但客戶不甲意。
參考
Difference of behavior abaout Fullwidth space in sql between sql server 2008 R2 and 2012