How to compare values which may both be null in T-SQL

后端 未结 14 1789
情书的邮戳
情书的邮戳 2020-12-23 14:20

I want to make sure I\'m not inserting a duplicate row into my table (e.g. only primary key different). All my fields allow NULLS as I\'ve decided null to mean \"all values

14条回答
  •  我在风中等你
    2020-12-23 14:55

    Above, @drowa shows a verbose approach that I agree with. It's good because it avoids the 3-value logic problem. Many of the other approaches provided here will fail in subtle and unexpected ways when negated because they're treating null as equivalent to false which it is not.

    However, I have a workflow that I find makes it convenient-ish, here's a regex. Given code of the form

    (leftSide <=> rightSide)
    

    regex find this:

    \(([a-zA-Z0-9_.@]+)\s*<=>\s*([a-zA-Z0-9_.@]+)\)
    

    and replace with this:

    (/*$1 <=> $2*/ ($1 IS NULL AND $2 IS NULL) OR ($1 IS NOT NULL AND $2 IS NOT NULL AND $1 = $2))
    

    So I write the (leftSide <=> rightSide) code and apply the above regex transformation to get the expanded form. It'd be nicer if MSSQL offered some kind of macro expansion so I wouldn't have to do it manually, but it doesn't.

    @Drowa's answer quoted for reference:

    Equals comparison:

    ((f1 IS NULL AND f2 IS NULL) OR (f1 IS NOT NULL AND f2 IS NOT NULL AND f1 = f2))
    

    Not Equal To comparison: Just negate the Equals comparison above.

    NOT ((f1 IS NULL AND f2 IS NULL) OR (f1 IS NOT NULL AND f2 IS NOT NULL AND f1 = f2))
    

    Is it verbose? Yes, it is. However it's efficient since it doesn't call any function. The idea is to use short circuit in predicates to make sure the equal operator (=) is used only with non-null values, otherwise null would propagate up in the expression tree.

提交回复
热议问题