0

为什么内置布尔函数在NULL输入上的行为不同?例如 - 这个查询:

select 'ISDATE(null)'                 as function_call, 
        ISDATE(null) as result union all
select 'ISNUMERIC(null)'              as function_call, 
        ISNUMERIC(null) as result union all
select 'IS_MEMBER(null)'              as function_call, 
        IS_MEMBER(null) as result union all
select 'IS_SRVROLEMEMBER(null, null)' as function_call, 
        IS_SRVROLEMEMBER(null, null) as result

给我们:

function_call                result
---------------------------- -----------
ISDATE(null)                 0
ISNUMERIC(null)              0
IS_MEMBER(null)              NULL
IS_SRVROLEMEMBER(null, null) NULL

看起来ISDATE, 的ISNUMERIC行为符合布尔逻辑,但是IS_MEMBER, IS_SRVROLEMEMBER- 的行为符合三值逻辑。不应该所有布尔函数在 NULL 输入上的行为都相同吗?ANSI SQL 标准对此有何规定?

谢谢

4

2 回答 2

3

重新ANSI标准,后两个函数与ANSI SQL无关;它们是 MSSQL 特定的安全功能。这并不是说它们在其他 DBMS 中没有类似物,只是它们不是“典型的”UML 样式函数或标准的一部分。

事实上,在这个相当权威的 O'Reilly 页面上搜索关于 ANSI 标准函数的术语“布尔”没有返回任何结果。可以由此推断,对于此类标量函数处理 NULL 没有 ANSI 方法。

在这些函数中需要三值逻辑以允许 NULL 表示输入无效。例如,请参阅MSDN的备注部分。IS_MEMBER()

(这种形式的 NULL 返回不应与例如可能返回值的聚合函数相混淆,或者如果其输入之一为 NULL,则为 NULL。)

没有什么可以阻止您“包装”这些功能以使其表现得像其他功能,如果那是您真正需要的。例如ISNULL(IS_MEMBER(someValueFromATable),0)

如您所见,前两个函数返回一个有意义的布尔值。

ISDATE(null),例如,返回 false 因为 null不是有效的日期、时间或日期时间”(MSDN,我强调)。

在 NULL 被解释为“未知”的情况下,ISDATE()当输入未知但在编程上不实用时,etc 返回“未知”在语义上是有意义的;当我们已经对ISNULL().

在比较您确定的两种类型的函数时,在这种情况下,后者的返回不应为 NULL,因为虽然 NULL 不是日期,但它仍然是可以正确检查的有效数据通过这个功能。

于 2013-04-18T11:26:49.357 回答
0

我不觉得这些安全功能 ( IS_SRVROLEMEMBER) 的行为与系统/数据类型功能 ( ISNUMERIC) 不同,因为这些安全功能本质上是查询,结果可能会根据查询的人而改变。返回值的含义,包括空值,在MSDN 文档中对所有这些都进行了很好的说明。

更具体地说,对于ISNUMERICand的参数ISDATE,如果参数为 null 与否,您可以提前很好地测试,所以我不确定返回 null 是必要的,或者是否有很多实用性。

对于安全函数的参数,您可能有非 null 参数,但这些函数以一种有用的方式构建,以在参数无效、未找到或您没有权限的情况下返回 null知道答案。

其中大部分内容当然可以被视为主观的,因此我投票结束这个问题,无论它可能多么有趣。

于 2013-04-18T15:10:51.683 回答