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;
Run Code Online (Sandbox Code Playgroud)
以上无法处理源端或目标端 name/dob 为空的情况。因为与 NULL 的比较返回 false。这要怎么处理呢?
例子:
COALESCE(S.NAME,'')<>COALESCE(T.NAME,'')
Run Code Online (Sandbox Code Playgroud)
或者
COALESCE(S.NAME,0)<>COALESCE(T.NAME,0)
Run Code Online (Sandbox Code Playgroud)
或者
NULLIF(S.NAME,'')<>NULLIF(T.NAME,'')
Run Code Online (Sandbox Code Playgroud)
EXISTS( SELECT src.* EXCEPT SELECT tgt.* )检测语句中源行是否与目标行不同MERGE INTO。EXCEPT 能成功地比较NULL值, andNULL与NOT NULL值,而(正如您所注意到的)=and<>运算符却不能。
IS DISTINCT FROM另一种选择是对每一列使用,但是 SQL Server 还不支持此功能。WITH HOLDLOCK. 与 非常重要MERGE。就像这样:
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...;
Run Code Online (Sandbox Code Playgroud)
具体来说,就您的情况而言:
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";
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3099 次 |
| 最近记录: |