视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
SQLServer中NULL的正确使用与空间占用
2020-11-09 07:02:20 责编:小采
文档


我们常在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。

    为了清晰的理解上述的内容,我们创建一个测试表Test_NULL,然后对表插入2条含有NULL值的记录,并进行相关验证操作:

    --创建一张允许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。

    下载本文
    显示全文
    专题