1,當心ISNULL函數對你的邏輯引起BUG 有人喜歡或者習慣於(並不代表我推薦,甚至這種寫法沒有任何好處)用ISNULL處理變數這種方式寫查詢 比如:select * from TestISNULL where name = ISNULL(@name,name) @name相當於傳入到存儲過程中的 ...
1,當心ISNULL函數對你的邏輯引起BUG
有人喜歡或者習慣於(並不代表我推薦,甚至這種寫法沒有任何好處)用ISNULL處理變數這種方式寫查詢
比如:select * from TestISNULL where name = ISNULL(@name,name)
@name相當於傳入到存儲過程中的參數,如果@name為null,
相當於:select * from TestISNULL where name = name,看起來恆成立,是真的嗎?
目的是在@name為null的時候,這個查詢條件不生效
當時當遇到欄位name中的某些數據為null的時候,實際邏輯就變成了
select * from TestISNULL where null= null,null=null是什麼結果?
自己試試或者繼續往下看就知道了,
此時會產生一些“莫名其妙”的bug,這種bug是跟數據有關,有時候出現,而有時候又沒有問題,
對於“有時候出現有時候不出現的問題”,不管是SQL還是應用程式代碼,定位起來都不是太容易的
這種情況,會對對問題的排查產生了很大的干擾
看例子:
--ISNULL 處理變數的一個小陷阱 Create Table TestISNULL ( id int, name varchar(50) ) GO insert into TestISNULL values (1,'AAA') insert into TestISNULL values (2,'BBB') GO declare @name varchar(50) set @name=null select * from TestISNULL where name = ISNULL(@name,name) --結果是兩行沒有任何問題 /* id name ----------- ---------------------- 1 AAA 2 BBB (2 row(s) affected) */ --插入一條數據 insert into TestISNULL values (3,null) GO select * from TestISNULL --全部結果是三行 /* id name ----------- -------------------- 1 AAA 2 BBB 3 NULL (3 row(s) affected) */
--繼續用isnull的方式處理變數做查詢 declare @name varchar(50) set @name=null select * from TestISNULL where name = ISNULL(@name,name) --結果是兩行,你明白為什麼嗎 /* id name ----------- ---------------------- 1 AAA 2 BBB (2 row(s) affected)
究竟為什麼呢?好看,下麵應該很清楚了
2,SQL Server 對數據類型優先順序引起Case When 的一些語法錯誤
繼續用上面的表驗證另外一個小語法問題,某些邏輯處理數據的時候,欄位為null的時候,將結果統一標記為一種數值,如下
當然,這樣是通不過的,提示將AAA轉換為數值的時候失敗
這種問題本質上是:會將低優先順序的varchar轉換為高優先順序的int進行對比
但是在將字元轉換為數值型的時候,就會出現轉換失敗的情況
這裡就涉及到SQL Server數據類型優先順序的問題,有興趣的自行MSDN
SELECT id, CASE WHEN name IS NULL THEN 0 ELSE name END AS name FROM TestISNULL
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'AAA' to data type int.
解決辦法就是統一數據類型,註意字元0和數值0是不一樣的,這樣就不會引起數據類型優先順序轉換的問題
SELECT id, CASE WHEN name IS NULL THEN '0' ELSE name END AS name FROM TestISNULL
當然這個問題的“變種”不僅限於case when,有各種各樣的“變種”,
當遇到“Error converting data type *** to ***.”此類問題的時候,可以考慮是不是這個原因引起的,對快速定位問題可以起到幫助作用,避免在這些小邏輯上浪費太多時間。