2010-05-19 34 views
4

SET ANSI_NULLS OFF似乎取決於是否你是從一個表或值進行比較的字段得到不同的結果在TSQL。任何人都可以幫助我理解爲什麼最後2個查詢沒有結果?我不是在尋找解決方案,只是一個解釋。ANSI_NULLS如何在TSQL中工作?

select 1 as 'Col' into #a 
select NULL as 'Col' into #b 

--This query gives results, as expected. 
SET ANSI_NULLS OFF 
select * from #b 
where NULL = Col 

--This query gives results, as expected. 
SET ANSI_NULLS OFF 
select * from #a 
where NULL != Col 

--This workaround gives results, too. 
select * from #a a, #b b 
where isnull(a.Col, '') != isnull(b.Col, '') 

--This query gives no results, why? 
SET ANSI_NULLS OFF 
select * from #a a, #b b 
where a.Col != b.Col 

--This query gives no results, why? 
SET ANSI_NULLS OFF 
select * from #a a, #b b 
where b.Col != a.Col 
+0

我剛剛偶然發現這一點,我覺得就我以前從來不知道這一點。我一直認爲SQL的行爲方式與在Java/.NET中對NULL進行比較的方式相同。 – 2012-03-01 07:12:47

回答

10

究其原因,最後兩個查詢失敗是當你對一個變量或NULL值比較是SET ANSI_NULLS ON/OFF才適用。它不適用於比較列值的情況。從BOL:

SET ANSI_NULLS ON影響的比較 僅當 比較的操作數之一可以是一個變量,它是 NULL或文字NULL。如果比較的兩個 雙方都列或 複合表達式中,設置不 不會影響比較。

+0

你知道爲什麼它會以這種方式工作嗎? – RossFabricant 2010-05-19 17:46:29

+1

@rossfabricant - 禁用ANSI_NULLS的能力是爲了向後兼容(即,永遠設定它關閉的原因可以一方面進行計數用手指遺留)成爲可能。所以,我懷疑原因必須是因爲以這種方式運行的SQL的較早實現。 – Thomas 2010-05-19 18:09:11

0

與空值相比的任何事情都失敗。即使比較兩個空值也會失敗。即使是!=也會因爲(恕我直言)對NULL的愚蠢處理而失敗。

這就是說,=查詢可以改寫說:

select * from #a a where a.Col not in (select b.Col from #b b) 

最後的查詢是相同的倒數第二個查詢作爲比較的順序並不重要。

順便說一句,你的變通辦法,只是因爲你正在測試在#b.Col列空值,並明確地將其轉換成「」,然後讓你的查詢做他們之間的字符串比較。寫的另一種方式是:

select * from #a a, #b b 
where a.Col != COALESCE(b.Col, '')