而後當你用 SET 關鍵字給變量賦值的話,sql server 將爲這個值分配內存空間並將地址存放在變量列表(variable table)中。若是你再次爲這個變量賦值的話新的內存地址將替換舊的地址。 sql
下面咱們就來討論一下 「= NULL」和「IS NULL」的區別。 數據庫
「= NULL」 post
「= NULL」是值表達式。意味着,這個表達式會判斷是否已經爲變量正確設置了值。事實上咱們是能夠設置一個變量的值爲 NULL 的(若是設置變量 = NULL,這就說明變量的值是未知的 unknown)。參考下面的代碼。 .net
DECLARE @val CHAR(4) 3d
SET @val = NULL server
咱們顯式給變量賦值 NULL,sql server會爲變量分配內存空間並指出變量值是未知的 unknown,所以下面的表達式將返回 true(由於咱們已經經過 SET @val = NULL 爲變量分配了內存空間): 內存
If @val = NULL get
但若是咱們像下面的代碼段同樣在申明變量的時候不給變量賦值: table
DECLARE @val CHAR(4) class
If @val = NULL
表達式將返回 false。
致使這種狀況的緣由是,在沒有給變量賦值的狀況下,sql server 是不會爲變量分配內存空間,所以地址是未知的就沒法進行值的比較了。
Note: 上面的示例結果與 ANSI_NULLS (ON|OFF) 的設置有關。
「IS NULL」
「IS NULL」的狀況就有點微妙,在須要比較變量值是否是爲 NULL 的時候它應該是首選的用法。IS NULL 會同時檢查變量地址和變量的地址所指向的值是否是未知的(unknown)。研究一下下面的代碼:
上面兩個表達式都會返回 TRUE, 緣由是 IS NULL 同時比較地址和值是否是未知的。
環境變量 SET ANSI_NULLS (ON|OFF) 的設置對 「= NULL」的表達式會有很大的影響,下面的段落摘錄自sql server 的幫助,它很好的解釋了這一因素。(SET ANSI_NULLS 詳細的說明參考sql server 幫助)
SQL-92 標準要求對空值的等於 (=) 或不等於 (<>) 比較取值爲 FALSE。當 SET ANSI_NULLS 爲 ON 時,即便 column_name 中存在空值,使用 WHERE column_name = NULL 的 SELECT 語句仍返回零行。即便 column_name 中存在非空值,使用 WHERE column_name <> NULL 的 SELECT 語句仍返回零行。
當 SET ANSI_NULLS 爲 OFF 時,等於 (=) 和不等於 (<>) 比較運算符不聽從 SQL-92 標準。使用 WHERE column_name = NULL 的 SELECT 語句返回 column_name 中含有空值的行。使用 WHERE column_name <> NULL 的 SELECT 語句返回列中含有非空值的行。此外,使用 WHERE column_name <> XYZ_value 的 SELECT 語句返回全部非 XYZ 值和非 NULL的行。
當 SET ANSI_NULLS 爲 ON 時,全部對空值的比較均取值爲 UNKNOWN。當 SET ANSI_NULLS 爲 OFF 時,若是數據值是 NULL,則全部數據對空值的比較將取值爲 TRUE。若是未指定,則應用當前數據庫的 ANSI nulls 選項的設置。
爲使腳本按預期運行,無論 ANSI nulls 數據庫選項或 SET ANSI_NULLS 的設置是什麼,在可能包含空值的比較中使用 IS NULL 和 IS NOT NULL。
因此咱們在須要判斷NULL的時候最好使用 IS NULL 和 IS NOT NULL。儘可能避免使用 = NULL 和 <> NULL, 由於後者會產生非預期的效果。
在 SET ANSI_NULLS 設置不一樣時下面的 sql 語句會產生不一樣結果:
SELECT * FROM t1 WHERE a = NULL
SELECT * FROM t1 WHERE a <> NULL
SELECT * FROM t1 WHERE a IS NULL
原文地址 http://baodr.com/post/2008/04/IS-NULL-and-3d-NULL-e59ca8-sql-server-e4b8ade79a84e58cbae588ab.aspx