Sql 合并-多个匹配的案例与更新

Sql 合并-多个匹配的案例与更新,sql,sql-server,merge,Sql,Sql Server,Merge,启动此请求时,我收到SQL Server编号错误10714。 我知道我不能在MATHED时使用多个更新,但我不知道该怎么做 MERGE INTO Photo p USING TmpPhoto tp ON p.ProductNumberID = tp.ProductNumberID and p.SHA1 = tp.SHA1 WHEN MATCHED AND p.Rank = tp.Rank THEN UPDATE SET p.VerifiedDate = getDate() WHEN MA

启动此请求时,我收到SQL Server编号错误10714。 我知道我不能在MATHED时使用多个更新,但我不知道该怎么做

MERGE INTO Photo p
USING TmpPhoto tp
ON p.ProductNumberID = tp.ProductNumberID and p.SHA1 = tp.SHA1
WHEN MATCHED AND p.Rank = tp.Rank THEN
    UPDATE SET p.VerifiedDate = getDate()
WHEN MATCHED AND p.Rank != tp.Rank AND tp.Rank != 1 THEN
    UPDATE SET p.VerifiedDate = getDate(), p.Rank = tp.Rank, p.Active = 0
WHEN MATCHED AND p.Rank != tp.Rank AND tp.Rank = 1 THEN
    UPDATE SET p.VerifiedDate = getDate(), p.Rank = tp.Rank, p.Active = 1
WHEN NOT MATCHED THEN
    INSERT (ProductNumberID, Code, Extension, Rank, CreatedDate, VerifiedDate, FCTH, SHA1, Active)
    VALUES (tp.ProductNumberID, tp.Code, tp.Extension, tp.Rank, getdate(), getdate(), tp.FCTH, tp.SHA1, 0)
    OUTPUT inserted.NumberID as PhotoNumberID, inserted.ProductNumberID, inserted.SHA1, inserted.Rank INTO InsertedPhotos;

如果可以,在
UPDATE
子语句中使用
CASE
表达式来模拟匹配时具有多个
子句的行为。大概是这样的:

MERGE INTO Photo p
USING TmpPhoto tp
ON p.ProductNumberID = tp.ProductNumberID and p.SHA1 = tp.SHA1
WHEN MATCHED THEN
    UPDATE 
       SET p.VerifiedDate = getDate(),
           p.Rank = CASE 
                        WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN tp.Rank                       
                        ELSE p.Rank
                    END,
           p.Active = CASE
                          WHEN p.Rank = tp.Rank THEN p.Active 
                          WHEN tp.Rank != 1 THEN 0
                          ELSE 1
                      END
WHEN NOT MATCHED THEN
    INSERT (ProductNumberID, Code, Extension, Rank, CreatedDate, VerifiedDate, FCTH, SHA1, Active)
    VALUES (tp.ProductNumberID, tp.Code, tp.Extension, tp.Rank, getdate(), getdate(), tp.FCTH, tp.SHA1, 0)
    OUTPUT inserted.NumberID as PhotoNumberID, inserted.ProductNumberID, inserted.SHA1, inserted.Rank INTO InsertedPhotos;
这样做的目的是将关于哪些字段要更新以及如何更新的逻辑移动到
CASE
表达式中。请注意,如果不更新某个字段,则只需将其设置为自身。在SQL Server中,这似乎是不允许的。但是,我不确定它是否会算作触发器的修改列。您可以随时测试触发器中的行是否实际更改,以避免此方法可能导致的任何问题。

简化版(始终更新verifiedDate,始终更新秩,因为如果相等,则保持不变,唯一更改的字段是p。使用
CASE

您是否考虑过在执行更新时使用语句

这里可能有语法问题。让我知道这是否有效

MERGE INTO Photo p
USING TmpPhoto tp
    ON p.ProductNumberID = tp.ProductNumberID
    AND p.SHA1 = tp.SHA1
WHEN MATCHED THEN
    UPDATE SET p.VerifiedDate = GETDATE()
        , p.Rank = CASE
            WHEN p.Rank != tp.Rank THEN tp.Rank
            ELSE p.Rank
        END
        , p.Active = CASE
            WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN 0
            WHEN p.Rank != tp.Rank AND tp.Rank = 1 THEN 1
            ELSE p.Active
        END
WHEN NOT MATCHED THEN
    INSERT (ProductNumberID, Code, Extension, Rank, CreatedDate, VerifiedDate, FCTH, SHA1, Active)
    VALUES (tp.ProductNumberID, tp.Code, tp.Extension, tp.Rank, getdate(), getdate(), tp.FCTH, tp.SHA1, 0)
    OUTPUT inserted.NumberID as PhotoNumberID, inserted.ProductNumberID, inserted.SHA1, inserted.Rank INTO InsertedPhotos;
你为什么不试着用语句

MERGE INTO 
      Photo p
USING 
      TmpPhoto tp  ON p.ProductNumberID = tp.ProductNumberID 
                   AND p.SHA1 = tp.SHA1
WHEN 
    MATCHED AND p.Rank = tp.Rank 
THEN
    UPDATE 
        SET    p.VerifiedDate = GETDATE(),
               p.Rank = CASE 
                            WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN tp.Rank
                            WHEN p.Rank != tp.Rank AND tp.Rank  = 1 THEN tp.Rank
                            ELSE p.Rank END,
               p.Active = CASE 
                            WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN 0
                            WHEN p.Rank != tp.Rank AND tp.Rank  = 1 THEN 1
                            ELSE p.Active END
WHEN 
    NOT MATCHED
THEN
    INSERT (ProductNumberID, Code, Extension, Rank, CreatedDate, VerifiedDate, FCTH, SHA1, Active)
    VALUES (tp.ProductNumberID, tp.Code, tp.Extension, tp.Rank, getdate(), getdate(), tp.FCTH, tp.SHA1, 0)
    OUTPUT inserted.NumberID as PhotoNumberID, inserted.ProductNumberID, inserted.SHA1, inserted.Rank INTO InsertedPhotos;

可能的重复不是完全重复,但它提供了线索。您刚刚忘记了CASE后面的单词(参见其他答案…)何时更新了我的答案。谢谢你的注意
MERGE INTO 
      Photo p
USING 
      TmpPhoto tp  ON p.ProductNumberID = tp.ProductNumberID 
                   AND p.SHA1 = tp.SHA1
WHEN 
    MATCHED AND p.Rank = tp.Rank 
THEN
    UPDATE 
        SET    p.VerifiedDate = GETDATE(),
               p.Rank = CASE 
                            WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN tp.Rank
                            WHEN p.Rank != tp.Rank AND tp.Rank  = 1 THEN tp.Rank
                            ELSE p.Rank END,
               p.Active = CASE 
                            WHEN p.Rank != tp.Rank AND tp.Rank != 1 THEN 0
                            WHEN p.Rank != tp.Rank AND tp.Rank  = 1 THEN 1
                            ELSE p.Active END
WHEN 
    NOT MATCHED
THEN
    INSERT (ProductNumberID, Code, Extension, Rank, CreatedDate, VerifiedDate, FCTH, SHA1, Active)
    VALUES (tp.ProductNumberID, tp.Code, tp.Extension, tp.Rank, getdate(), getdate(), tp.FCTH, tp.SHA1, 0)
    OUTPUT inserted.NumberID as PhotoNumberID, inserted.ProductNumberID, inserted.SHA1, inserted.Rank INTO InsertedPhotos;