-2
MERGE TARGET T
USING SOURCE S
ON T.ID=S.ID

WHEN MATCHED AND (S.NAME<>T.NAME OR S.DOB<>T.DOB)
THEN UPDATE
SET T.NAME=S.NAME, T.DOB=S.DOB;

The above is not able to handle situation where name/dob is null on source or target side. Because comparisons with NULL return false. How to handle this?

Example:

COALESCE(S.NAME,'')<>COALESCE(T.NAME,'')

Or

COALESCE(S.NAME,0)<>COALESCE(T.NAME,0)

Or

NULLIF(S.NAME,'')<>NULLIF(T.NAME,'')
variable
  • 8,262
  • 9
  • 95
  • 215

1 Answers1

5

Like so:

MERGE INTO destTable WITH (HOLDLOCK) AS tgt
USING srcRelation AS src ON
    /* Only specify PK columns here: */
    tgt.Pk1 = src.Pk1
    AND
    tgt.Pk2 = src.Pk2

WHEN MATCHED AND EXISTS (

    /*
    Only specify "data" columns here; these are the columns which are also included in the UPDATE SET clause below.
    Don't include GENERATED, rowversion, PRIMARY KEY, and other "non-data" columns
    */

    SELECT tgt.Col1, tgt.Col2, tgt.Col3, etc
    EXCEPT
    SELECT src.Col1, src.Col2, src.Col3, etc
)
THEN UPDATE SET
    tgt.Col1 = src.Col1,
    tgt.Col2 = src.Col2,
    tgt.Col3 = src.Col3

WHEN NOT MATCHED BY TARGET THEN etc...;

Specifically, in your case:

MERGE INTO "target" WITH (HOLDLOCK) AS tgt
USING "source" AS src ON
    tgt."ID" = src."ID"
WHEN MATCHED AND EXISTS (
    SELECT tgt."Name"
    EXCEPT
    SELECT src."Name"
)
THEN UPDATE SET
    tgt."Name" = src."Name";
Dai
  • 141,631
  • 28
  • 261
  • 374
  • Does COALESCE not cover any scenario that is covered by your code example? – variable Mar 29 '22 at 08:16
  • 2
    @variable As others have pointed out in their comment-replies already: **`COALESCE` is inappropriate in this case** because it doesn't indicate that `''` is distinct from `NULL`, not to mention introducing other ambiguities w.r.t. data-types. Point is: **you should not** use `COALSECE` (nor `ISNULL`) in a `MERGE ... WHEN MATCHED AND...` clause. - whereas `EXISTS ( SELECT src... EXCEPT SELECT tgt... )` is idiomatic in T-SQL and _works as-expected_. – Dai Mar 29 '22 at 08:18
  • 3
    @variable and using `coalesce` can result in the query being unsargable i.e. unable to use indexes. Hence this is a better solution. (You did ask for the best way to do it :) ) – Dale K Mar 29 '22 at 08:24