我今天遇到了与此类似的代码。
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 :(得分: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
在您将其放入表格或以其他方式与某些上下文元数据相关联之前,这会给您带来什么?它有什么区别INT
或DATETIME
或其他什么?您将如何处理这些信息?
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()返回第一个参数的数据类型,并为其提供数据类型。
答案 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值。