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
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.
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.
Did you check NULLIF? http://msdn.microsoft.com/en-us/library/ms177562.aspx
NULLIF(TARGET.relation_id, SOURCE.app_relation_id) IS NULL Simple solution
You will have to use IS NULL or ISNULL. There really isn't a away around it.
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:
ISNULL(NULLIF(A, B), NULLIF(B, A)) IS NULL
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