SQL Server中NULL的正確使用與空間占用
我們常在SQL Server的使用或維護(hù)中遇上NULL,那么什么是NULL?如下是MSDN給出的一段簡(jiǎn)短描述(見(jiàn)“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就是一個(gè)值,而且這個(gè)值是未知的(unknown);NULL不能等價(jià)任何值,甚至都不等價(jià)它自己,即NULL不等于NULL。
為了清晰的理解上述的內(nèi)容,我們創(chuàng)建一個(gè)測(cè)試表Test_NULL,然后對(duì)表插入2條含有NULL值的記錄,并進(jìn)行相關(guān)驗(yàn)證操作:
--創(chuàng)建一張?jiān)试SNULL值的表 CREATE TABLE Test_NULL ( num INT NOT NULL PRIMARY KEY ,fname NVARCHAR(50) NULL ,lname NVARCHAR(50) NULL ) --對(duì)表插入4條數(shù)據(jù):最后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')
為了驗(yàn)證NULL值是未知的,我們通過(guò)如下SQL查詢(xún)表Test_NULL的記錄,對(duì)lname字段進(jìn)行=操作:
--若兩個(gè)NULL是可以相等的,那么將輸出4條記錄。實(shí)際只輸出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 --查詢(xún)lname為''的記錄,即驗(yàn)證NULL不等于'' SELECT * FROM Test_NULL tn WHERE tn.lname = '' ------------------------------------------ 2 Dave
正確查詢(xún)/使用SQL Server中的NULL
由于NULL是未知的,因此在SQL Server默認(rèn)情況下我們不能使用=或<>去判斷或查詢(xún)一條NULL的記錄(見(jiàn)上述),正確的方式是:使用IS NULL或IS NOT NULL去查詢(xún)或過(guò)濾一條含有NULL的記錄。
另外有函數(shù)ISNULL(),可判斷并轉(zhuǎn)換NULL為其他值。
--通過(guò)IS NULL查詢(xún)含有NULL的記錄 SELECT * FROM Test_NULL tn WHERE tn.lname IS NULL ------------------------------------------ 3 Aaron NULL 4 Betty NULL --NULL不等于任何值,甚至NULL不等于NULL --默認(rèn)不能使用<>或=匹配N(xiāo)ULL SELECT * FROM Test_NULL tn WHERE tn.lname <> NULL OR tn.lname = NULL ------------------------------------------
但需注意:SQL Server僅是在默認(rèn)情況下不能使用=或<>,當(dāng)設(shè)置ANSI_NULLS為OFF后,即可使用=或<>查詢(xún)NULL值
換言之,SQL Server默認(rèn)是開(kāi)啟ANSI_NULLS選項(xiàng)的。
--設(shè)置ANSI_NULLS為OFF,并使用=NULL查詢(xún)記錄 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的空間占用
通常的認(rèn)識(shí)是:NULL在可變長(zhǎng)類(lèi)型(如nvarchar(50),varchar(8))中是不占用空間的,在固定長(zhǎng)度的類(lèi)型(如int)中會(huì)占用存儲(chǔ)空間。
實(shí)際上,上述的認(rèn)識(shí)不夠嚴(yán)謹(jǐn)。真實(shí)情況是,NULL在可變長(zhǎng)與固定長(zhǎng)度的類(lèi)型中均會(huì)占用空間
在SQL Server非Sparse Columns中,存儲(chǔ)NULL的值需1個(gè)bit的NULL bitmap mask。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
- SQLserver查詢(xún)數(shù)據(jù)類(lèi)型為ntext是空或NULL值的方法
- sqlserver對(duì)字段出現(xiàn)NULL值的處理
- sqlserver isnull在數(shù)據(jù)庫(kù)查詢(xún)中的應(yīng)用
- SQL Server、Oracle和MySQL判斷NULL的方法
- 深入SQLServer中ISNULL與NULLIF的使用詳解
- 淺談SQLServer的ISNULL函數(shù)與Mysql的IFNULL函數(shù)用法詳解
- sqlserver 不能將值NULL插入列id(列不允許有空值解決)
- SQLSERVER ISNULL 函數(shù)與判斷值是否為空的sql語(yǔ)句
- 在SQL Server中使用ISNULL執(zhí)行空值判斷查詢(xún)
相關(guān)文章
SQL Server阻止保存修改表結(jié)構(gòu)的解決方法
修改DeUser表中列的數(shù)據(jù)類(lèi)型從varchar修改為int時(shí),進(jìn)行保存時(shí)彈出的提示框,阻止保存修改表結(jié)構(gòu),怎么辦?這篇文章就為大家詳細(xì)介紹了解決SQL Server阻止保存修改表結(jié)構(gòu)問(wèn)題的方法,感興趣的小伙伴們可以參考一下2016-05-05
SQLServer恢復(fù)表級(jí)數(shù)據(jù)詳解
這篇文章主要介紹了SQLServer中用于快速恢復(fù)表,而不是庫(kù),但是切記,防范總比亡羊補(bǔ)牢好,需要的朋友可以參考下2014-08-08
SQL Server 利用觸發(fā)器對(duì)多表視圖進(jìn)行更新的實(shí)現(xiàn)方法
這篇文章主要介紹了SQL Server 利用觸發(fā)器對(duì)多表視圖進(jìn)行更新的實(shí)現(xiàn)方法,需要的朋友可以參考下2016-10-10
強(qiáng)制SQL Server執(zhí)行計(jì)劃使用并行提升在復(fù)雜查詢(xún)語(yǔ)句下的性能
最近在給一個(gè)客戶做調(diào)優(yōu)的時(shí)候發(fā)現(xiàn)一個(gè)很有意思的現(xiàn)象,對(duì)于一個(gè)復(fù)雜查詢(xún)(涉及12個(gè)表)建立必要的索引后,語(yǔ)句使用的IO急劇下降,但執(zhí)行時(shí)間不降反升,由原來(lái)的8秒升到20秒。2014-07-07
SQL Server中檢查字段的值是否為數(shù)字的方法
這篇文章主要介紹了SQL Server中檢查字段的值是否為數(shù)字的方法,使用ISNUMERIC函數(shù)實(shí)現(xiàn),需要的朋友可以參考下2014-06-06
利用ROW_NUMBER() OVER函數(shù)給SQL數(shù)據(jù)庫(kù)中每一條記錄分配行號(hào)的方法
這篇文章主要介紹了利用ROW_NUMBER() OVER函數(shù)給SQL數(shù)據(jù)庫(kù)中每一條記錄分配行號(hào)的方法,需要的朋友可以參考下2015-10-10
SQL Server 2012使用Offset/Fetch Next實(shí)現(xiàn)分頁(yè)數(shù)據(jù)查詢(xún)
在Sql Server 2012之前,實(shí)現(xiàn)分頁(yè)主要是使用ROW_NUMBER(),在SQL Server2012,可以使用Offset ...Rows Fetch Next ... Rows only的方式去實(shí)現(xiàn)分頁(yè)數(shù)據(jù)查詢(xún),具體代碼詳解大家參考下本文2017-07-07

