T SQL合并示例需要帮助理解

下列:

MERGE dbo.commissions_history AS target USING (SELECT @amount, @requestID) AS source (amount, request) ON (target.request = source.request) WHEN MATCHED THEN UPDATE SET amount = source.amount WHEN NOT MATCHED THEN INSERT (request, amount) VALUES (source.request, source.amount); 

从https://stackoverflow.com/a/2967983/857994是一个非常漂亮的方式来做插入/更新(和删除一些额外的工作)。 即使经过一些Googlesearch,我也发现很难跟踪。

有人可以请:

  • 简单地解释一下 – MSDN文档在这种情况下会毁掉我的大脑。
  • 向我展示如何修改它,以便用户可以键入数量和请求的值,而不是从另一个数据库位置select它们?

基本上,我想用它来从C#应用程序中插入/更新从我得到的XML文件中获取的信息。 所以,我需要了解如何手动制定一个查询来获取我的分析数据到这个机制的数据库。

如果你不熟悉连接语句,那么这就是你需要开始的地方。 了解联结如何工作是rest的关键。 一旦你熟悉了连接,那么理解合并是最简单的,因为它是一个完整的连接,并指示如何处理或不匹配的行。

所以,使用提供的代码示例可以查看表commissions_history

 | Amount | Request | <other fields | -------------------------------------------- | 12.00 | 1234 | <other data | | 14.00 | 1235 | <other data | | 15.00 | 1236 | <other data | 

merge语句在称为“目标”的表和称为“源”的expression式之间创build一个完全连接,该表返回一个称为“源”的表(或者一个与CTE类似的表,在逻辑上非常类似的结果集)。

在给出的示例中,它使用variables作为我们假设已经由用户设置或作为parameter passing的源。

 DECLARE @Amount Decimal = 18.00; DECLARE @Request Int = 1234; MERGE dbo.commissions_history AS target USING (SELECT @amount, @requestID) AS source (amount, request) ON (target.request = source.request) 

当想到连接时,创build以下结果集。

 | Amount | Request | <other fields | Source.Amount | Source.Request | ------------------------------------------------------------------------------ | 12.00 | 1234 | <other data | 18.00 | 1234 | | 14.00 | 1235 | <other data | null | null | | 15.00 | 1236 | <other data | null | null | 

在find匹配的情况下,根据给出的指示对目标执行什么操作。

 WHEN MATCHED THEN UPDATE SET amount = source.amount 

结果目标performance在看起来像这样。 具有请求1234的行被更新为18。

 | Amount | Request | <other fields | -------------------------------------------- | 18.00 | 1234 | <other data | | 14.00 | 1235 | <other data | | 15.00 | 1236 | <other data | 

由于比赛WAS发现没有其他事情发生。 但是,让我们说来源的价值是这样的。

 DECLARE @Amount Decimal = 18.00; DECLARE @Request Int = 1239; 

生成的连接看起来像这样:

 | Amount | Request | <other fields | Source.Amount | Source.Request | ------------------------------------------------------------------------------ | 12.00 | 1234 | <other data | null | null | | 14.00 | 1235 | <other data | null | null | | 15.00 | 1236 | <other data | null | null | | null | null | null | 18.00 | 1239 | 

由于在目标中找不到匹配的行,所以语句执行另一个子句。

 WHEN NOT MATCHED THEN INSERT (request, amount) VALUES (source.request, source.amount); 

导致目标表格如下所示:

 | Amount | Request | <other fields | -------------------------------------------- | 12.00 | 1234 | <other data | | 14.00 | 1235 | <other data | | 15.00 | 1236 | <other data | | 18.00 | 1239 | <other data | 

合并报表真正的潜力是源和目标都是大型表。 因为它可以用一个简单的语句为每一行执行大量的更新和/或插入操作。

最后的笔记。 请记住, not matched默认值与not matched的完整子句not matched by target是非常重要的,但是您可以指定not matched by source代替默认子句或者除了默认子句之外。 合并语句同时支持两种不匹配(源中的logging不在目标中,或者目标中的logging不在on中定义的 )。 您可以在MSDN上find完整的文档,限制和完整的语法。

在给出的答案中,你已经完成了

 DECLARE @Request Int 

,但在SQL中调用它如下:

 SELECT @amount, @requestID 

另一个是命名和调用variables相同:

 @amount vs. Amount -> @Amount & Amount