SQL 服务器合并删除与过滤器
Posted
技术标签:
【中文标题】SQL 服务器合并删除与过滤器【英文标题】:SQL server merge Delete with filter 【发布时间】: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
【问题讨论】:
【参考方案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。以上是关于SQL 服务器合并删除与过滤器的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin函数式编程 ② ( 过滤函数 | predicate 谓词函数 | filter 过滤函数 | 合并函数 | zip 函数 | folder 函数 | 函数式编程意义 )
Kotlin函数式编程 ② ( 过滤函数 | predicate 谓词函数 | filter 过滤函数 | 合并函数 | zip 函数 | folder 函数 | 函数式编程意义 )