SQL Server中NULL的正確使用與空間占用
我們常在SQL Server的使用或維護中遇上NULL,那么什么是NULL?如下是MSDN給出的一段簡短描述(見“Null Values”):
- A value of NULL indicates that the value is unknown. A value of NULL is different from an empty or zero value. No two null values are equal. Comparisons between two null values, or between a NULL and any other value, return unknown because the value of each NULL is unknown.
通俗的講,NULL就是一個值,而且這個值是未知的(unknown);NULL不能等價任何值,甚至都不等價它自己,即NULL不等于NULL。
為了清晰的理解上述的內容,我們創(chuàng)建一個測試表Test_NULL,然后對表插入2條含有NULL值的記錄,并進行相關驗證操作:
--創(chuàng)建一張允許NULL值的表 CREATE TABLE Test_NULL ( num INT NOT NULL PRIMARY KEY ,fname NVARCHAR(50) NULL ,lname NVARCHAR(50) NULL ) --對表插入4條數據:最后2條記錄含有NULL值 INSERT INTO Test_NULL (num,fname,lname) VALUES(1, 'Tom','Jane') INSERT INTO Test_NULL (num,fname,lname) VALUES(2, 'Dave','') INSERT INTO Test_NULL (num,fname) VALUES(3, 'Aaron') INSERT INTO Test_NULL (num,fname) VALUES(4, 'Betty')
為了驗證NULL值是未知的,我們通過如下SQL查詢表Test_NULL的記錄,對lname字段進行=操作:
--若兩個NULL是可以相等的,那么將輸出4條記錄。實際只輸出2條記錄
SELECT * FROM Test_NULL tn LEFT JOIN Test_NULL g ON tn.num = g.num WHERE tn.lname = g.lname ------------------------------------------ 1 Tom Jane 1 Tom Jane 2 Dave 2 Dave --查詢lname為''的記錄,即驗證NULL不等于'' SELECT * FROM Test_NULL tn WHERE tn.lname = '' ------------------------------------------ 2 Dave
正確查詢/使用SQL Server中的NULL
由于NULL是未知的,因此在SQL Server默認情況下我們不能使用=或<>去判斷或查詢一條NULL的記錄(見上述),正確的方式是:使用IS NULL或IS NOT NULL去查詢或過濾一條含有NULL的記錄。
另外有函數ISNULL(),可判斷并轉換NULL為其他值。
--通過IS NULL查詢含有NULL的記錄 SELECT * FROM Test_NULL tn WHERE tn.lname IS NULL ------------------------------------------ 3 Aaron NULL 4 Betty NULL --NULL不等于任何值,甚至NULL不等于NULL --默認不能使用<>或=匹配NULL SELECT * FROM Test_NULL tn WHERE tn.lname <> NULL OR tn.lname = NULL ------------------------------------------
但需注意:SQL Server僅是在默認情況下不能使用=或<>,當設置ANSI_NULLS為OFF后,即可使用=或<>查詢NULL值
換言之,SQL Server默認是開啟ANSI_NULLS選項的。
--設置ANSI_NULLS為OFF,并使用=NULL查詢記錄 SET ANSI_NULLS OFF SELECT * FROM Test_NULL tn WHERE tn.lname = NULL ------------------------------------------ 3 Aaron NULL 4 Betty NULL
插入或更新NULL值:
--插入1條含有NULL的新記錄 INSERT INTO Test_NULL (num,fname,lname) VALUES(5, 'Serena', NULL) --更新某條記錄的字段值為NULL UPDATE Test_NULL SET fname = NULL WHERE num = 2
NULL的空間占用
通常的認識是:NULL在可變長類型(如nvarchar(50),varchar(8))中是不占用空間的,在固定長度的類型(如int)中會占用存儲空間。
實際上,上述的認識不夠嚴謹。真實情況是,NULL在可變長與固定長度的類型中均會占用空間
在SQL Server非Sparse Columns中,存儲NULL的值需1個bit的NULL bitmap mask。
以上就是本文的全部內容,希望對大家的學習有所幫助。
相關文章
SQL Server 利用觸發(fā)器對多表視圖進行更新的實現方法
這篇文章主要介紹了SQL Server 利用觸發(fā)器對多表視圖進行更新的實現方法,需要的朋友可以參考下2016-10-10
強制SQL Server執(zhí)行計劃使用并行提升在復雜查詢語句下的性能
最近在給一個客戶做調優(yōu)的時候發(fā)現一個很有意思的現象,對于一個復雜查詢(涉及12個表)建立必要的索引后,語句使用的IO急劇下降,但執(zhí)行時間不降反升,由原來的8秒升到20秒。2014-07-07
利用ROW_NUMBER() OVER函數給SQL數據庫中每一條記錄分配行號的方法
這篇文章主要介紹了利用ROW_NUMBER() OVER函數給SQL數據庫中每一條記錄分配行號的方法,需要的朋友可以參考下2015-10-10
SQL Server 2012使用Offset/Fetch Next實現分頁數據查詢
在Sql Server 2012之前,實現分頁主要是使用ROW_NUMBER(),在SQL Server2012,可以使用Offset ...Rows Fetch Next ... Rows only的方式去實現分頁數據查詢,具體代碼詳解大家參考下本文2017-07-07

