为什么 ISNULL(NULL, NULL) 返回 int 数据类型?

moh*_*iri -2 sql t-sql sql-server

基于对的返回类型部分文件ISNULL()

返回与check_expression相同的类型。如果文字NULL作为check_expression提供,则返回replacement_value的数据类型。如果文字NULL作为check_expression提供并且没有提供replacement_value,则返回int.

为什么在这种情况下ISNULL()返回一个int

Mar*_*ith 8

为什么SELECT ISNULL(NULL, NULL)返回一个类型的列INT

NULL没有任何其他上下文的文字通常int在 SQL Server 中被视为。所以这与“返回与”相同的类型是一致的check_expression

如果您这样做SELECT NULL AS Col INTO SomeTable并查看创建的列数据类型,您也可以看到这一点。

或者再次可以在这个愚蠢的递归 CTE 示例中看到它

WITH R(C) AS
(
SELECT NULL 
UNION ALL 
SELECT 0.0 FROM R WHERE 1 = 0
)
SELECT *
FROM R
Run Code Online (Sandbox Code Playgroud)

哪个返回

消息 240,级别 16,状态 1,第 1 行类型在递归查询“R”的“C”列中的锚点和递归部分之间不匹配。

但是0.0替换为可以正常工作,0因此递归部分中的列是int而不是decimal.

为什么它的行为是这样的?

这正是 SQL Server 决定采用的方式。我怀疑他们会出于向后兼容的原因改变行为,即使它有点武断并且可能与 SQL 标准不一致

这一切的有些随意性也表现在

SELECT NULLIF(NULL, NULL)
Run Code Online (Sandbox Code Playgroud)

您可能希望它以相同的方式运行并返回一个,INT但您会收到一个错误

NULLIF 的第一个参数的类型不能是 NULL 常量,因为必须知道第一个参数的类型。

COALESCE(NULL,NULL)返回

COALESCE 的至少一个参数必须是一个不是 NULL 常量的表达式。