SQL Server中NULL的正确使用与空间占用
我们常在SQLServer的使用或维护中遇上NULL,那么什么是NULL?如下是MSDN给出的一段简短描述(见“NullValues”):
- AvalueofNULLindicatesthatthevalueisunknown.AvalueofNULLisdifferentfromanemptyorzerovalue.Notwonullvaluesareequal.Comparisonsbetweentwonullvalues,orbetweenaNULLandanyothervalue,returnunknownbecausethevalueofeachNULLisunknown.
通俗的讲,NULL就是一个值,而且这个值是未知的(unknown);NULL不能等价任何值,甚至都不等价它自己,即NULL不等于NULL。
为了清晰的理解上述的内容,我们创建一个测试表Test_NULL,然后对表插入2条含有NULL值的记录,并进行相关验证操作:
--创建一张允许NULL值的表 CREATETABLETest_NULL( numINTNOTNULLPRIMARYKEY ,fnameNVARCHAR(50)NULL ,lnameNVARCHAR(50)NULL ) --对表插入4条数据:最后2条记录含有NULL值 INSERTINTOTest_NULL(num,fname,lname)VALUES(1,'Tom','Jane') INSERTINTOTest_NULL(num,fname,lname)VALUES(2,'Dave','') INSERTINTOTest_NULL(num,fname)VALUES(3,'Aaron') INSERTINTOTest_NULL(num,fname)VALUES(4,'Betty')
为了验证NULL值是未知的,我们通过如下SQL查询表Test_NULL的记录,对lname字段进行=操作:
--若两个NULL是可以相等的,那么将输出4条记录。实际只输出2条记录
SELECT * FROMTest_NULLtn LEFTJOINTest_NULLg ONtn.num=g.num WHEREtn.lname=g.lname ------------------------------------------ 1TomJane1TomJane 2Dave2Dave --查询lname为''的记录,即验证NULL不等于'' SELECT * FROMTest_NULLtn WHEREtn.lname='' ------------------------------------------ 2Dave
正确查询/使用SQLServer中的NULL
由于NULL是未知的,因此在SQLServer默认情况下我们不能使用=或<>去判断或查询一条NULL的记录(见上述),正确的方式是:使用ISNULL或ISNOTNULL去查询或过滤一条含有NULL的记录。
另外有函数ISNULL(),可判断并转换NULL为其他值。
--通过ISNULL查询含有NULL的记录 SELECT * FROMTest_NULLtn WHEREtn.lnameISNULL ------------------------------------------ 3AaronNULL 4BettyNULL --NULL不等于任何值,甚至NULL不等于NULL --默认不能使用<>或=匹配NULL SELECT * FROMTest_NULLtn WHEREtn.lname<>NULLORtn.lname=NULL ------------------------------------------
但需注意:SQLServer仅是在默认情况下不能使用=或<>,当设置ANSI_NULLS为OFF后,即可使用=或<>查询NULL值
换言之,SQLServer默认是开启ANSI_NULLS选项的。
--设置ANSI_NULLS为OFF,并使用=NULL查询记录 SETANSI_NULLSOFF SELECT * FROMTest_NULLtn WHEREtn.lname=NULL ------------------------------------------ 3AaronNULL 4BettyNULL
插入或更新NULL值:
--插入1条含有NULL的新记录 INSERTINTOTest_NULL(num,fname,lname)VALUES(5,'Serena',NULL) --更新某条记录的字段值为NULL UPDATETest_NULLSETfname=NULL WHEREnum=2
NULL的空间占用
通常的认识是:NULL在可变长类型(如nvarchar(50),varchar(8))中是不占用空间的,在固定长度的类型(如int)中会占用存储空间。
实际上,上述的认识不够严谨。真实情况是,NULL在可变长与固定长度的类型中均会占用空间
在SQLServer非SparseColumns中,存储NULL的值需1个bit的NULLbitmapmask。
以上就是本文的全部内容,希望对大家的学习有所帮助。