SQL MERGE:是否可以忽略 MATCH?

SQL MERGE: Is it possible to ignore a MATCH?

这是我的合并语句:

MERGE PE_TranslationPhrase T
USING PE_TranslationPhrase_Staging S 
ON (T.CultureName = S.CultureName AND T.Phrase = S.Phrase)
WHEN MATCHED 
        THEN UPDATE SET T.TranslationId = T.TranslationId -- do nothing
WHEN NOT MATCHED BY TARGET
        THEN INSERT (TranslationId, CultureName, Phrase)
        VALUES (S.TranslationId, S.CultureName, S.Phrase);

我似乎在使用 WHEN MATCHED 部分时遇到了问题。基于 ,我将 WHEN MATCHED 更改为:

THEN UPDATE SET T.TranslationId = T.TranslationId

但我仍然收到此错误:

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.

我明白了。根据 ON 语句,我得到了重复的匹配项。但是……我不在乎。如果来自源 table 的记录已经存在于目标 table 中,那么我什么都不做。不要更新任何东西。略过。

这可能吗?

哦。结果表明您不需要 'WHEN MATCHED' 语句。我认为这是必需的。

MERGE PE_TranslationPhrase T
USING PE_TranslationPhrase_Staging S 
ON (T.CultureName = S.CultureName AND T.Phrase = S.Phrase)
WHEN NOT MATCHED BY TARGET
        THEN INSERT (TranslationId, CultureName, Phrase)
        VALUES (S.TranslationId, S.CultureName, S.Phrase);

不幸的是,在MERGE 语句中什么也做不了,就省略了这个错误。但是我已经通过生成一个标识列(非持久性)解决了这个问题,该标识列允许我为句子的 sourcetarget 的每个记录添加一个唯一值并比较表格。像这样:

ROW_NUMBER () OVER (PARTITION BY CultureName, Phrase ORDER BY CultureName, Phrase)

如果没有进行更新,您是否考虑过使用 PE_TranslationPhrase_Staging 中不在 PE_TranslationPhrase 中的行进行插入?

CTE 方法:

WITH CTE AS (
SELECT 
    S.TranslationId, 
    S.CultureName, 
    S.Phrase
FROM PE_TranslationPhrase_Staging S 
LEFT JOIN PE_TranslationPhrase T on S.Phrase = T.Phrase and S.CultureName = T.CultureName
WHERE T.PHRASE IS NULL
)

INSERT INTO PE_TranslationPhrase (TranslationId, CultureName, Phrase)
SELECT 
    TranslationId, 
    CultureName, 
    Phrase
FROM CTE

子查询方法:

INSERT INTO PE_TranslationPhrase (TranslationId, CultureName, Phrase)
SELECT 
TW.TranslationId, 
TW.CultureName, 
TW.Phrase
FROM (
SELECT 
    S.TranslationId, 
    S.CultureName, 
    S.Phrase
FROM PE_TranslationPhrase_Staging S 
LEFT JOIN PE_TranslationPhrase T on S.Phrase = T.Phrase and S.CultureName = T.CultureName
WHERE T.PHRASE IS NULL ) TW

不,您不能在存在多个匹配项的情况下使用 Merge ... When Matched ...,正如您所发现的,您可以简单地删除 When Matched 部分。但是,如果您需要此部分用于 update,而不是使用 Merge,您可以使用以下代码:

update PE_TranslationPhrase
set  TranslationId = S.xxx
from
PE_TranslationPhrase T, PE_TranslationPhrase_Staging S
where T.CultureName = S.CultureName AND T.Phrase = S.Phrase