2013-03-26 38 views
6

我今天遇到类似这样的代码。NULL是否有数据类型?

SELECT AuditDomain, 
    ObjectId, 
    AuditSubdomain = CONVERT(VARCHAR(50), NULL), 
    SubDomainObjectId = CONVERT(INT, NULL) 
FROM Audit 

它似乎意味着数据类型信息可以与NULL值相关联。这是否将元数据附加到将其标识为指定数据类型的NULL值?

This post详细办法找到SQL Server中的数据类型,但是当我尝试下面一行它回来为NULL:

SELECT CAST(SQL_VARIANT_PROPERTY(CONVERT(INT, NULL), 'BaseType') AS VARCHAR(20)) 
+0

你有没有试过Google搜索“空数据类型”?您可能会发现它不是数据类型......上述代码的工作原因是因为varchar可能为空。 – RandomUs1r 2013-03-26 21:20:32

回答

12

在SQL Server中,NULLINT默认情况下,所有的我能想到的情景。你可以用下面的代码确定此:

SELECT x = NULL INTO #x; 
EXEC tempdb..sp_columns '#x'; 

结果:

TABLE_QUALIFIER TABLE_OWNER TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME 
--------------- ----------- ---------- ----------- --------- --------- 
tempdb   dbo   #x___... x   4   int 

你已经把之前到表或以其他方式与一些上下文元数据相关联的,是什么给你买?它与INTDATETIME或其他什么有什么不同?你将如何处理这些信息?

SQL_VARIANT_PROPERTY返回NULL,因为它似乎要求元数据的值是有意义的。观察(使用不同类型的只是混合起来):

SELECT SQL_VARIANT_PROPERTY(NULL, 'BaseType'); 

DECLARE @x DATE; 

SELECT SQL_VARIANT_PROPERTY(@x, 'BaseType'); 

DECLARE @y DATE = SYSDATETIME(); 

SELECT SQL_VARIANT_PROPERTY(@y, 'BaseType'); 

结果:

NULL 

NULL 

date 

所以它似乎既需要一个类型值,以便准确判断基本类型。

至于为什么它这样工作,耸耸肩。你必须要求访问源代码的人。

请注意,NULL只有在您强制SQL Server的时候才需要采用基本类型:您已经基于此创建了一个表。在这种情况下,SQL Server可能会返回一个错误(事实上在许多情况下,它必须猜测你的数据类型)。避免这种情况的方法是不要创建SQL Server必须猜测的情况(这就是为什么我问,为什么要使用这些信息?)。

+0

为什么'sql_variant_property'函数返回'NULL'你有答案吗? – ErikE 2013-03-26 21:40:26

+0

@ErikE那合适? – 2013-03-26 21:47:27

+0

这与UNION一起使用。这两个表格没有相同的模式,而第二个表格缺少一列,他们放置了这些CONVERT(,NULL)语句。我已经运行了多个测试,在这里我使用NULL来代替转换,并且一切都按预期工作。也许这是对UNION和/或类型转换如何工作的误解。 – Jason 2013-03-26 22:11:23

0

我知道你已经有一些很好的答案,但SQL_VARIANT_PROPERTY我觉得被误解了。

您将SQL_Variant_Property与列一起使用,然后指示您想要的元数据属性。但是,如果它是空的,它不会告诉你很多。

EG:

declare 
    @Start date = getdate() 
, @End datetime= getdate() 
, @Int int = 1 
, @DateNull date 
; 


select 
    sql_variant_property(@Start, 'BaseType') 
, sql_variant_property(@End, 'BaseType') 
, sql_variant_property(@Int, 'BaseType') 
, sql_variant_property(@DateNull, 'BaseType') 

将返回三个数据类型和空。处理NULL是SQL的重要组成部分。很多人,包括我自己在内,有时希望用价值来表示它,否则在其他时候不关心。 SQL Variant只能使用参数'BaseType'工作,否则它将返回一个空值。据我所知这是由于SQL说:“你没有数据,没有什么可以确定内存使用。”

通常我会指定isnull(@thing,0),当我使用整数时,我明确地希望数据集包含未知数的零。在其他时候,我希望有一个用户知道一个null事件为某个报告做了别的事情(@thing,'not present')。还有一些时候,你可以使用coalesce来实现一系列的posizities coalesce(@thing,@otherthing,@yotheotherthing,'unknown')。

我认为在代码中你正在见证某人正在转换某些东西,因为我不确定你真的需要做这样的事情。表中的列的数据类型保持其所需的内容,并且当SQL为NULL时,SQL不会将内存存储在其中。所以需要改变它似乎任意恕我直言。我知道,如果您希望通过SQL 2008中引入的SPARSE选项获得更多的空值,那么您可以处理更好的内存消耗。但是,我不知道什么时候可以将几乎没有任何消耗的东西投入更多。

0

couse NULL有数据类型。 尝试下一编码确认:

SELECT 
    CAST(NULL AS date) AS c1, 
    CAST(NULL AS time) AS c2 
INTO #x; 
EXEC tempdb..sp_columns '#x'; 

,我认为有错误的SQL_VARIANT实现,因为它有关NULL类型损耗信息。太糟糕了!

0

我不同意@ aaron-bertrand。自从默认情况下,SQl服务器创建了具有整数数据类型的列来存储NULL值,因为Null可以插入到Int,Datetime,Date,Varchar任何其他列中。

在表中插入空值时使用 SELECT x = NULL INTO #x;

SQl服务器创建的整数类型列默认为Null,可以插入Integer列。

所以可能是由于我们编写的查询的性质“SELECT x = NULL INTO #x;”这使列作为整数并将NULL值。

相关问题