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

后端 未结 14 1624
情书的邮戳
情书的邮戳 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 15:08

    You create a primary key on your fields and let the engine enforce the uniqueness. Doing IF EXISTS logic is incorrect anyway as is flawed with race conditions.

    0 讨论(0)
  • 2020-12-23 15:09

    You could use SET ANSI_NULLS in order to specify the behavior of the Equals (=) and Not Equal To (<>) comparison operators when they are used with null values.

    0 讨论(0)
  • 2020-12-23 15:11

    Did you check NULLIF? http://msdn.microsoft.com/en-us/library/ms177562.aspx

    0 讨论(0)
  • 2020-12-23 15:13

    NULLIF(TARGET.relation_id, SOURCE.app_relation_id) IS NULL Simple solution

    0 讨论(0)
  • 2020-12-23 15:14

    You will have to use IS NULL or ISNULL. There really isn't a away around it.

    0 讨论(0)
  • 2020-12-23 15:15

    I needed a similar comparison when doing a MERGE:

    WHEN MATCHED AND (Target.Field1 <> Source.Field1 OR ...)
    

    The additional checks are to avoid updating rows where all the columns are already the same. For my purposes I wanted NULL <> anyValue to be True, and NULL <> NULL to be False.

    The solution evolved as follows:

    First attempt:

    WHEN MATCHED AND
    (
        (
            -- Neither is null, values are not equal
            Target.Field1 IS NOT NULL
                AND Source.Field1 IS NOT NULL
                AND Target.Field1 <> Source.Field1
        )
        OR
        (
            -- Target is null but source is not
            Target.Field1 IS NULL
                AND Source.Field1 IS NOT NULL
        )
        OR
        (
            -- Source is null but target is not
            Target.Field1 IS NOT NULL
                AND Source.Field1 IS NULL
        )
    
        -- OR ... Repeat for other columns
    )
    

    Second attempt:

    WHEN MATCHED AND
    (
        -- Neither is null, values are not equal
        NOT (Target.Field1 IS NULL OR Source.Field1 IS NULL)
            AND Target.Field1 <> Source.Field1
    
        -- Source xor target is null
        OR (Target.Field1 IS NULL OR Source.Field1 IS NULL)
            AND NOT (Target.Field1 IS NULL AND Source.Field1 IS NULL)
    
        -- OR ... Repeat for other columns
    )
    

    Third attempt (inspired by @THEn's answer):

    WHEN MATCHED AND
    (
    
        ISNULL(
            NULLIF(Target.Field1, Source.Field1),
            NULLIF(Source.Field1, Target.Field1)
        ) IS NOT NULL
    
        -- OR ... Repeat for other columns
    )
    

    The same ISNULL/NULLIF logic can be used to test equality and inequality:

    • Equality: ISNULL(NULLIF(A, B), NULLIF(B, A)) IS NULL
    • Inequaltiy: ISNULL(NULLIF(A, B), NULLIF(B, A)) IS NOT NULL

    Here is an SQL-Fiddle demonstrating how it works http://sqlfiddle.com/#!3/471d60/1

    0 讨论(0)
提交回复
热议问题