简体   繁体   中英

t-sql: incompatibility between built-in boolean functions

Why built-in boolean functions behaves differently on NULL input ? For example - this query:

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

gives us:

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

So seems that ISDATE , ISNUMERIC behaves according to boolean logic, but IS_MEMBER , IS_SRVROLEMEMBER - behaves according to Three valued logic . Shouldn't all boolean functions behave the same on NULL input ? What ANSI SQL standard says about that ?

Thanks

Re ANSI standards, the latter two functions have nothing to do with ANSI SQL; They're MSSQL specific security functions. Which is not to suggest they don't have analogues in other DBMSs, just that they're not "typical" UML style functions or part of the standard.

I'm fact, a search on this reasonably authoritative O'Reilly page about ANSI standard functions for the term "Boolean" returns no results. One may infer from this that there is no ANSI approach to such scalar functions' handling of NULLs.

The three valued logic is required in those functions to allow NULL to signify that an input is not valid . eg Refer to Remarks section of MSDN IS_MEMBER() .

(This form of NULL return is not to be confused with eg aggregate functions that may return a value, or NULL if one of its inputs was NULL.)

There's nothing stopping you "wrapping" those functions to behave like the others, if that's what you really need. Eg ISNULL(IS_MEMBER(someValueFromATable),0) .

The former two functions return a meaningful Boolean value, as you've found.

ISDATE(null) , for example, returns false because null is not a " valid date, time, or datetime value " ( MSDN , my emphasis on value ).

In the case where NULL is interpreted to mean "unknown", it would be semantically meaningful for ISDATE() etc to return "unknown" when the input is unknown, but not programatically practical; The need to "convert" the result (from all these boolean functions) from three-state to boolean logic is completely redundant when we already have a separate type-non-specific test for ISNULL() .

In comparing the two types of functions you've identified, the return for the latter ones shouldn't be NULL in this case, because while NULL isn't a date, it is still certainly a valid piece of data that can be properly examined by this function.

I don't find it odd that these security functions ( IS_SRVROLEMEMBER ) would behave differently from system/datatype functions ( ISNUMERIC ) since these security functions are essentially queries and the results can change depending upon who is querying. The meanings of the return values, including nulls, are spelled out very well for all of these in the MSDN Documentation .

More concretely, for the arguments to ISNUMERIC and ISDATE , you can test very well ahead of time if the argument is null or not, so I'm not sure that returning a null is necessary, or has much practicality.

For the arguments to the security functions, you may have non-null arguments, but the functions have been built in a helpful manner to return null in cases where the arguments aren't valid, not found, or you don't have the permissions to know the answer.

Much of this can certainly be seen as subjective, thus I have voted to close this question, however interesting it may be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM