【问题标题】:SQL server merge Delete with filterSQL 服务器合并删除与过滤器
【发布时间】:2014-10-01 13:35:53
【问题描述】:

我正在使用合并进行插入或删除,但我不确定它应该是什么样子。我有一个映射表,将分类法映射到支持的语言。该表如下所示:

TaxonomyLanguageID(PK) | TaxonomyID(FK) | LanguageID(FK)

我想要做的是将临时表与上表合并,其中临时表将包含分类法支持的语言列表。例如:

TaxonomyID|LanguageID

456,        2

456,        3

456,        9

我尝试过的看起来像这样(选择用于测试,稍后这将是一个临时表):

MERGE dbo.TaxonomyLanguages as t
using (SELECT 5395  as TaxonomyID, 2 as LanguageID) as s
ON (s.TaxonomyID=T.TaxonomyID AND s.LanguageID=t.LanguageID)
WHEN NOT MATCHED BY TARGET THEN
    INSERT(TaxonomyID,LanguageID) VALUES(S.TaxonomyID,s.LanguageID)
WHEN NOT MATCHED BY SOURCE AND T.TaxonomyID=s.TaxonomyID
    THEN DELETE;

我想要做的是如果不匹配则插入,如果不匹配则删除,但只删除目标中与源中找到的分类 ID 匹配的那些行。

但我得到一个“只有目标列在'当源不匹配'子句中允许”错误。

关于如何解决这个问题(或应该如何完成)的任何想法?

我正在寻找的示例。如果我有来源喜欢

TaxonomyID|LanguageID

4000,      2

4000,      3

还有一个像这样的目标:

TaxonomyLanguageID|TaxonomyID|LanguageID

1,                  3000       2

2,                  4000       1

3,                  4000       2

最终结果是:

TaxonomyLanguageID|TaxonomyID|LanguageID

1,                 3000       2

3,                 4000       2

4,                 4000       3

【问题讨论】:

    标签: sql sql-server merge


    【解决方案1】:

    你必须把它分成两遍,因为关键字段的数量不同。

    Select 456 as TaxonomyID, 2 as LanguageID
      into TaxonomyLanguages
    
    INSERT INTO [dbo].[TaxonomyLanguages]
               ([TaxonomyID]
               ,[LanguageID])
         VALUES
               (456, 3)
               ,(456, 9)
    GO
    
    select *
    from [TaxonomyLanguages]
    
    
    MERGE dbo.TaxonomyLanguages as t
    using (SELECT 5395  as TaxonomyID, 2 as LanguageID) as s
    ON (s.TaxonomyID=T.TaxonomyID AND s.LanguageID=t.LanguageID)
    WHEN NOT MATCHED BY TARGET THEN
        INSERT(TaxonomyID,LanguageID) VALUES(S.TaxonomyID,s.LanguageID);
    
    
    MERGE dbo.TaxonomyLanguages as t
    using (SELECT 5395  as TaxonomyID, 2 as LanguageID) as s
    ON (s.TaxonomyID=T.TaxonomyID)
    WHEN NOT MATCHED BY SOURCE 
        THEN DELETE;
    
    select *
    from [TaxonomyLanguages]
    

    根据评论,更改第二次合并:

    MERGE dbo.TaxonomyLanguages as t
    using (SELECT 456  as TaxonomyID, 3 as LanguageID) as s
    ON (s.TaxonomyID=T.TaxonomyID)
    WHEN  MATCHED 
      and (s.LanguageID <> T.LanguageID)
        THEN DELETE;
    

    【讨论】:

    • 我的问题可能很糟糕,但这只会删除所有其他行。我只想删除与源中的 TaxonomyID 匹配的行,但不匹配 languageID。我会用一个例子来更新我的问题
    • 好的。然后使用 MATCHED 和过滤器。
    • 合并 dbo.TaxonomyLanguages as t using (SELECT 456 as TaxonomyID, 3 as LanguageID) as s ON (s.TaxonomyID=T.TaxonomyID) WHEN MATCHED 和 (s.LanguageID T.LanguageID)然后删除;
    【解决方案2】:
    MERGE SupplierProducts with (HOLDLOCK) AS TARGET
    USING (SELECT P.Id, P.ListPrice, P.SalesPrice FROM Products P) AS SOURCE ON (TARGET.Id = SOURCE.Id)
    
    WHEN MATCHED AND TARGET.Id = SOURCE.Id THEN
        UPDATE SET TARGET.ListPrice = SOURCE.ListPrice,
                   TARGET.Price = SOURCE.SalesPrice,
                   TARGET.UpdatedAt = GETDATE()
    
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (ProductId, ListPrice, Price)
        VALUES (SOURCE.Id, SOURCE.ListPrice, SOURCE.SalesPrice)
        
    WHEN NOT MATCHED BY SOURCE
        THEN DELETE
        OUTPUT
            left($action, 1) AS [Event],
            SOURCE.Id,
            DELETED.ListPrice AS OldListPrice,
            DELETED.Price AS OldPrice,
            INSERTED.ListPrice AS ListPrice,
            INSERTED.Price AS Price ,
            INSERTED.UpdatedAt;
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2013-09-24
    • 2015-09-24
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    相关资源
    最近更新 更多