NULL是否有数据类型?

时间:2013-03-26 21:16:53

标签: sql sql-server tsql 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))

5 个答案:

答案 0 :(得分:12)

在SQL Server中,NULL默认情况下是我能想到的所有场景中的INT。您可以使用以下代码确定:

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必须猜测的情况(这就是为什么我问,你会对这些信息做什么?)。

答案 1 :(得分:0)

Null没有数据类型。 null的目的是在值和类型中表示“未知”。

ISNULL()返回第一个参数的数据类型,并为其提供数据类型。

http://msdn.microsoft.com/en-us/library/ms187928.aspx

答案 2 :(得分:0)

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

您将SQL_Variant_Property与列一起使用,然后在其元数据属性上指示您想要的内容。但是如果它为null则不会告诉你太多。

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。处理NULL是SQL的重要组成部分。包括我自己在内的很多人有时希望用值来处理null来表示它,或者在其他时候不关心。 SQL Variant仅适用于带有参数的填充值:'BaseType',否则它将返回null。据我所知,这是由于SQL说:“你这里没有数据,没有什么可以确定内存使用。”

通常我在使用整数时指定isnull(@ thing,0)我明确地希望数据集包含未知数的零。在其他时候,我可能希望让用户知道一个空的发生,为报告做了别的事情(@thing,'not present')。还有一些时候你可以使用coalesce基本上是一系列的可能性合并(@ thing,@otherthing,@ yetotherthing,'unknown')。

我认为在代码中,当我不确定你真正需要做什么的时候,你正在见证某人正在转变某些东西。表中的列的数据类型保持其所需的状态,并且当它为NULL时,SQL不会在其中存储内存。所以改变它的需要似乎是随意的恕我直言。我知道你可以处理更好的内存消耗,当你期望使用我在SQL 2008中引入的SPARSE选项获得更多的空值时。但是我不知道什么时候可以投出几乎不需要更多东西的东西。

答案 3 :(得分: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类型的信息。太糟糕了!

答案 4 :(得分:0)

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

在表中插入Null时 SELECT x = NULL INTO #x;

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

因此可能是由于我们编写的查询的性质" SELECT x = NULL INTO #x;"这使得列成为整数并放入NULL值。