SQL Server MERGE

2025年3月17日 | 阅读 7 分钟

本文将详细解释 SQL Server 中的 MERGE 语句。它由 Microsoft 首次引入,随 SQL Server 2008 版本发布。MERGE 语句将 INSERT、UPDATE 和 DELETE 操作组合成一个语句,从而无需为每个操作编写单独的逻辑。它根据源表中的数据更改目标表中的数据。我们还可以指定要对 INSERT、UPDATE 或 DELETE 操作执行 MERGE 语句的条件。

我们还可以说,此语句将所需的表与目标表连接起来,然后对其执行必要的操作。此命令为修改我们复杂的 SQL 代码提供了更好的灵活性,从而提高了代码的可读性。它本质上是使用与其他表的键字段比较来更新现有表。

下面的解释有助于轻松理解这个概念

假设我们有两个表,源表和目标表,我们希望借助源表中存储的值来更新目标表。我们可以根据以下三种可能性来完成此操作

  1. 源表”中的某些行在“目标表”中未找到。在这种情况下,需要将源表中的行添加到目标表。
  2. 目标表”中的某些行在“源表”中未找到。在这种情况下,需要从目标表中删除行。
  3. 源表和目标表”中的某些行具有相同的键。但是,它们在非键列中具有不同的值。在这种情况下,需要使用“源表”中的数据更新“目标表”中的行。

“源表和目标表”以及相应的插入、更新和删除操作如下图所示

SQL Server MERGE

在引入 MERGE 语句之前,我们必须首先生成三个独立的语句(INSERT、UPDATE 和 DELETE)来更新目标表中的数据以匹配源表中的行。使用 MERGE 语句,我们现在可以在一个语句中执行所有这些过程。

语法

以下是说明 SQL Server 中 MERGE 语句的语法

在此语法中,我们首先在 MERGE 子句之后写入“目标表和源表”名称。其次,使用 ON 子句定义 merge_condition(类似于 join 子句中的 join_condition),该子句确定源表和目标表行如何匹配。通常,我们使用键列(主键或唯一键)来检索匹配的记录。merge_condition 以三种形式评估结果:MATCHED、NOT MATCHED 和 NOT MATCHED BY SOURCE。

MATCHED:它表示符合合并条件的行。它们在图像中显示为蓝色。在这种形式中,我们将使用“源表”中给定的数据更新“目标表”中的字段。

NOT MATCHED:它表示在两个表(源表和目标表)中都不匹配的行。它们在图像中显示为橙色。在这种形式中,源表中的行必须添加到目标表中。这种形式通常被称为 NOT MATCHED BY TARGET。

NOT MATCHED BY SOURCE:它表示目标表中的记录,并且在源表中没有找到匹配的记录。它们在图像中显示为绿色。在这种形式中,当我们希望将目标表与源表数据同步时,我们将从目标表中删除记录。

MERGE 语句示例

让我们了解 MERGE 语句如何在 SQL Server 中使用并实际实现它们。在这里,我们将创建两个简单的表,名为“Products”和“TargetProducts”,并向它们添加一些行。

执行以下脚本以创建两个表

表:Products

表:TargetProducts

我们可以通过执行如下 SELECT 语句来验证上述表

它将返回以下表格数据

SQL Server MERGE

现在我们将执行 MERGE 命令,并尝试使两个表相互同步。我们要做的第一件事是弄清楚如何管理 INSERT 操作。我们可以执行以下代码将新数据从源表合并到目标表

执行代码将返回以下输出

SQL Server MERGE

在此输出图像中,我们可以看到之前在目标数据库中不可用的产品 ID 为 3 和 4 的两条记录已被添加。此操作通过比较源表和目标表的产品 ID 列来执行。

更新操作

学习了用于在表中插入记录的 MERGE 查询后,我们将了解如何使用相同的语句更新值。为了更新值,需要在两个表中都有一个具有共同值的字段。数据库引擎只能匹配记录并执行更新;对给定列的更新操作将用于此目的。

这是代码脚本

执行代码将返回以下输出

SQL Server MERGE

在上面的输出图像中,我们可以看到目标表中产品“Desk”的初始值包含“150”。当我们执行 MERGE 命令时,它将更新所有匹配的记录,使其与源表中的条目相同。在这里,我们还可以看到更新代码已添加到插入命令之后。这表明 MERGE 语句可以在同一个脚本中执行插入和更新操作。

删除操作

学习了用于在表中插入和更新记录的 MERGE 语句后,我们现在将了解如何使用相同的语句从目标表中删除记录。

执行脚本将返回以下输出

SQL Server MERGE

在上面的图像中,我们可以看到产品 ID 为 5 和 6 的所有记录都从目标表中删除,因为它们不存在于源表中。在这种方法中,我们使用 MERGE 语句以一种非常简单有效的方法来管理复杂的业务需求。

使用 OUTPUT 记录 MERGE 更改

SQL Server 还允许我们使用 OUTPUT 子句记录 MERGE 语句的任何更改。因此,如果我们想总结 MERGE 语句执行的所有操作,则需要编辑现有代码以包含以下输出操作。下面的代码将生成执行合并的记录列表,以及对每条记录执行的操作。

执行上述语句将生成 MERGE 语句执行的输出操作

SQL Server MERGE

SQL Server 中 MERGE 语句的重要提示

尽管我们已经从一开始就了解了 MERGE 语句的所有信息,以及如何更改代码以包含插入、更新和删除操作的逻辑,但在准备 MERGE 代码时仍有一些其他重要注意事项需要牢记。这些注意事项如下

  • MERGE 语句的末尾应使用分号。如果我们不加分号,将抛出错误。
  • 编写 MERGE 语句后,我们还可以使用 SELECT @@RowCount 来查看更新的记录数。
  • MERGE 语句至少需要指定一个 MATCHED 子句才能获取结果。
  • 执行 MERGE 语句必须对源表具有 SELECT 权限,对目标表具有 INSERT、UPDATE 和 DELETE 权限。
  • SQL Server 不允许我们在同一个匹配子句中两次更新同一个变量

结论

在这篇文章中,我们通过多个示例探讨了 Merge 语句的各个方面。此语句提高了性能,因为所有数据只读取和处理一次。在分析源表和目标表中的数据时,早期版本需要三个单独的语句来执行三个不同的操作,例如 INSERT、UPDATE 或 DELETE。