为什么 SQL Server 2005 认为 COUNT(...) 可以为空?
Why does SQL Server 2005 think COUNT(...) is nullable?
当我做的时候
CREATE VIEW Test1 AS
WITH OneRow AS (SELECT a = 1)
SELECT countt = COUNT(*)
FROM OneRow
GO
SELECT COLUMN_NAME, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Test1'
我明白了
COLUMN_NAME IS_NULLABLE
----------- -----------
countt YES
我原以为 IS_NULLABLE
是 NO
,因为我认为 COUNT(*)
总是 return 是一个数字。
是否存在 COUNT(*)
可以 return NULL
的情况?将它包装成 ISNULL(COUNT(*), 0)
有什么危险吗?这似乎很奇怪,这是必要的。确实,有没有什么场景 COUNT(
anything)
可以 return NULL
?
我认为您的特定情况永远不会在该计算列中看到 NULL,而且我认为将列包装在 ISNULL() 中不会有问题。 SQL 服务器通常将计算列报告为 NULLABLE。
来自https://technet.microsoft.com/en-US/library/ms191250.aspx:
The Database Engine automatically determines the nullability of
computed columns based on the expressions used. The result of most
expressions is considered nullable even if only nonnullable columns
are present, because possible underflows or overflows will produce
null results as well. Use the COLUMNPROPERTY function with the
AllowsNull property to investigate the nullability of any computed
column in a table. An expression that is nullable can be turned into a
nonnullable one by specifying ISNULL(check_expression, constant),
where the constant is a nonnull value substituted for any null result.
Why does SQL Server 2005 think COUNT(...) is nullable?
看看下面的例子
CREATE VIEW Test1 AS
WITH R216 AS
(
SELECT TOP (216) 1 AS X
FROM master..spt_values
)
SELECT COUNT(*) AS X
FROM R216 a, R216 b, R216 c, R216 d
这与您的示例非常相似。 COUNT
列从视图
投影
SELECT COLUMN_NAME, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Test1'
Returns
+-------------+-------------+
| COLUMN_NAME | IS_NULLABLE |
+-------------+-------------+
| X | YES |
+-------------+-------------+
可以看出这实际上可以return一个NULL
如下。
SET ANSI_WARNINGS, ARITHABORT OFF;
SELECT * FROM Test1
Returns
+------+
| X |
+------+
| NULL |
+------+
2,176,782,336
的 COUNT
溢出了 INT
并且使用上面弃用的选项 SET
意味着 NULL
是 return ed 而不是错误
用 ISNULL(,not_null_constant)
换行意味着该列可以被视为从未 returning NULL
.
以上内容也适用于 ROW_NUMBER
(或几乎任何数学表达式)这样的结构,它可以 return NULL
而不是像上面那样溢出。
通常,即使没有晦涩难懂的弃用 SET
选项,正确确定计算列的可空性也可能很棘手。
例如,MAX(not_null_column)
也永远不会 return NULL
当用作矢量聚合(带有 GROUP BY
)时 - 但是它 可以 return NULL
当用作针对空 table.
的标量聚合时
在绝大多数情况下 SQL 服务器假定任何计算的表达式都可以为空,并在文档中明确调用这一点,并建议在这种假设可能出现的情况下使用 ISNULL
造成问题。
当我做的时候
CREATE VIEW Test1 AS
WITH OneRow AS (SELECT a = 1)
SELECT countt = COUNT(*)
FROM OneRow
GO
SELECT COLUMN_NAME, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Test1'
我明白了
COLUMN_NAME IS_NULLABLE
----------- -----------
countt YES
我原以为 IS_NULLABLE
是 NO
,因为我认为 COUNT(*)
总是 return 是一个数字。
是否存在 COUNT(*)
可以 return NULL
的情况?将它包装成 ISNULL(COUNT(*), 0)
有什么危险吗?这似乎很奇怪,这是必要的。确实,有没有什么场景 COUNT(
anything)
可以 return NULL
?
我认为您的特定情况永远不会在该计算列中看到 NULL,而且我认为将列包装在 ISNULL() 中不会有问题。 SQL 服务器通常将计算列报告为 NULLABLE。
来自https://technet.microsoft.com/en-US/library/ms191250.aspx:
The Database Engine automatically determines the nullability of computed columns based on the expressions used. The result of most expressions is considered nullable even if only nonnullable columns are present, because possible underflows or overflows will produce null results as well. Use the COLUMNPROPERTY function with the AllowsNull property to investigate the nullability of any computed column in a table. An expression that is nullable can be turned into a nonnullable one by specifying ISNULL(check_expression, constant), where the constant is a nonnull value substituted for any null result.
Why does SQL Server 2005 think COUNT(...) is nullable?
看看下面的例子
CREATE VIEW Test1 AS
WITH R216 AS
(
SELECT TOP (216) 1 AS X
FROM master..spt_values
)
SELECT COUNT(*) AS X
FROM R216 a, R216 b, R216 c, R216 d
这与您的示例非常相似。 COUNT
列从视图
SELECT COLUMN_NAME, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Test1'
Returns
+-------------+-------------+
| COLUMN_NAME | IS_NULLABLE |
+-------------+-------------+
| X | YES |
+-------------+-------------+
可以看出这实际上可以return一个NULL
如下。
SET ANSI_WARNINGS, ARITHABORT OFF;
SELECT * FROM Test1
Returns
+------+
| X |
+------+
| NULL |
+------+
2,176,782,336
的 COUNT
溢出了 INT
并且使用上面弃用的选项 SET
意味着 NULL
是 return ed 而不是错误
用 ISNULL(,not_null_constant)
换行意味着该列可以被视为从未 returning NULL
.
以上内容也适用于 ROW_NUMBER
(或几乎任何数学表达式)这样的结构,它可以 return NULL
而不是像上面那样溢出。
通常,即使没有晦涩难懂的弃用 SET
选项,正确确定计算列的可空性也可能很棘手。
例如,MAX(not_null_column)
也永远不会 return NULL
当用作矢量聚合(带有 GROUP BY
)时 - 但是它 可以 return NULL
当用作针对空 table.
在绝大多数情况下 SQL 服务器假定任何计算的表达式都可以为空,并在文档中明确调用这一点,并建议在这种假设可能出现的情况下使用 ISNULL
造成问题。