[SQL Server][T-SQL]SQL語法夾帶全形空白導致語法錯誤

這週有個客戶的案子幾百隻程式上線,上線後的隔天早上,同事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

https://connect.microsoft.com/SQLServer/feedback/details/816220/-sql-server-difference-of-behavior-abaout-fullwidth-space-in-sql-between-sql-server-2008-r2-and-2012