为什么计数(1/空)有效,而计数(空/空)不起作用?



我最近在一次演讲中看到过这个例子。运行如下查询时:

SELECT COUNT(NULL)

您会收到以下错误:

操作数数据类型 NULL 对于计数运算符无效。

运行以下命令时:

SELECT COUNT(1/NULL)

结果是 0,即使除法本身产生 NULL。如果交换 1 和 NULL,也会发生同样的情况。

但是,如果您这样做:

SELECT COUNT(NULL/NULL)

您再次收到与第一个查询相同的错误(除法本身是合法的,产生 NULL(。

谁能解释一下sql server是如何工作的来给出这些结果的?

在 SQL Server 中,某些聚合函数(如 COUNT、MIN、MAX(和函数(如 DATEADD(需要数据类型。NULL,本身没有,所以这会给你一个错误:

SELECT COUNT(NULL) -- Operand data type NULL is invalid for count operator.

同样适用于:

SELECT COUNT(NULL/NULL)

对于1/NULL,数据类型为 INT,值为 NULL,因此可以这样做:

SELECT COUNT(1/NULL) -- 0

同样适用于:

SELECT COUNT(CAST(NULL AS INT)) -- 0

这实际上是一个编译器错误。运行批处理时,将分析 T-SQL,并在此时(而不是在执行时(绘制语句SELECT COUNT(NULL);SELECT COUNT(NULL/NULL);上的错误。

如果您运行下面的批处理,您将很快看到以下内容:

PRINT 'testing 1'
SELECT COUNT(NULL); --Error at compile
GO
PRINT 'testing 2'
SELECT COUNT(1/NULL); --Runs
GO
PRINT 'testing 3'
SELECT COUNT(NULL/NULL);  --Error at compile
GO
PRINT 'testing 4'
SELECT COUNT(0/0); --Error at run time

请注意,testing 1testing 3语句永远不会显示。

NULL本身没有数据类型。表达式的所有边都NULL的表达式实际上具有未知的数据类型。

如果要为NULL提供数据类型,则不会发生此问题:

PRINT 'testing 5'
SELECT COUNT(CONVERT(int,NULL));
GO
PRINT 'testing 6'
DECLARE @N int;
SELECT COUNT(@N);

问题出在所涉及的数据类型上。如果我们运行以下命令,我们可以看到 NULL 本身没有数据类型:

SELECT SQL_VARIANT_PROPERTY(NULL,'BaseType')

这对应于您看到的错误。

我们可以强制 NULL 使用强制转换选择数据类型,在这种情况下,错误得到解决:

SELECT COUNT(cast(NULL as int))

相关内容

  • 没有找到相关文章

最新更新