SQLServer中MERGE语句的使用,
目录
- 1、本文内容
- 2、语法
- 3、参数
- 4、备注
- 5、触发器的实现
- 6、权限
- 7、有关索引的最佳做法
- 8、MERGE 的并发注意事项
- 9、示例
- 9.1、借助派生的源表,使用 MERGE 对目标表执行 UPDATE 和 INSERT 操作
- 9.2、使用 MERGE 在一个语句中对表执行 INSERT 和 UPDATE 操作
- 9.3、使用 MERGE 在一个语句中对表执行 UPDATE 和 DELETE 操作
- 9.4、将 MERGE 语句的执行结果插入到另一个表中
- 9.5、使用 MERGE 对图形数据库中的目标边缘表执行 INSERT 或 UPDATE 操作
- 10、相关内容
在 SQL Server 中,MERGE 语句用于根据两个表之间的条件来插入、更新或删除记录。它通常用于同步两个表的数据,其中一个表是源表(包含要插入或更新的数据),另一个是目标表(数据要插入或更新的表)。
1、本文内容
- 语法
- 参数
- 备注
- 触发器的实现
- 权限
- 有关索引的最佳做法
- MERGE 的并发注意事项
- 示例
- 相关内容
适用于:
- SQL Server
- Azure SQL 数据库
- Azure SQL 托管实例
- Azure Synapse Analytics
根据与源表联接的结果,对目标表进行插入、更新或删除操作。 例如,根据与另一个表的区别,在一个表中插入、更新或删除行,从而同步两个表。
2、语法
SQL Server 和 Azure SQL 数据库的语法:
[ WITH <common_table_expression> [,...n] ]
MERGE
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]
USING <table_source> [ [ AS ] table_alias ]
ON <merge_search_condition>
[ WHEN MATCHED [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
THEN <merge_not_matched> ]
[ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
[ <output_clause> ]
[ OPTION ( <query_hint> [ ,...n ] ) ]
;
<target_table> ::=
{
[ database_name . schema_name . | schema_name . ] [ [ AS ] target_table ]
| @variable [ [ AS ] target_table ]
| common_table_expression_name [ [ AS ] target_table ]
}
<merge_hint>::=
{
{ [ <table_hint_limited> [ ,...n ] ]
[ [ , ] { INDEX ( index_val [ ,...n ] ) | INDEX = index_val }]
}
}
<merge_search_condition> ::=
<search_condition>
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
<merge_not_matched>::=
{
INSERT [ ( column_list ) ]
{ VALUES ( values_list )
| DEFAULT VALUES }
}
<clause_search_condition> ::=
<search_condition>
3、参数
WITH common_table_expression<>
指定在 MERGE 语句作用域内定义的临时命名结果集或视图,亦称为“公用表表达式”。 结果集派生自简单查询,并由 MERGE 语句引用。 有关详细信息,请参阅 WITH common_table_expression (Transact-SQL)。TOP ( expression ) [ PERCENT ]
指定受影响的行数或所占百分比。 expression 可以是行数或行百分比。 在 TOP 表达式中引用的行不是以任意顺序排列的。 有关详细信息,请参阅 TOP (Transact-SQL)。在整个源表和目标表联接,且不符合插入、更新或删除操作条件的联接行遭删除后,应用 TOP 子句。 TOP 子句进一步将联接行数减少到指定值。 这些操作(插入、更新或删除)以无序方式应用于其余联接行。 也就是说,在 WHEN 子句中定义的操作中,这些行是无序分布的。 例如,指定 TOP (10) 会影响 10 行。 在这些行中,可能会更新 7 行并插入 3 行,也可能会删除 1 行、更新 5 行并插入 4 行等。
如果源表上没有筛选器, MERGE 语句可能会对源表执行表扫描或聚集索引扫描,以及对目标表进行表扫描或聚集索引扫描。 因此,即使使用 TOP 子句通过创建多个批处理来修改大型表,I/O 性能有时也会受到影响。 在这种情况下,请务必要确保所有连续批处理都以新行为目标。
database_name
target_table 所在数据库的名称。schema_name
target_table 所属架构的名称。target_table
<table_source> 中的数据行根据 <clause_search_condition> 进行匹配的表或视图。 target_table 是由 MERGE 语句的 WHEN 子句指定的任何插入、更新或删除操作的目标。如果 target_table 为视图,则针对它的任何操作都必须满足更新视图所需的条件。 有关详细信息,请参阅通过视图修改数据。
target_table 不得是远程表。 target_table 不能定义其中的任何规则。target_table 不能是内存优化表。
可以将提示指定为 <merge_hint>。
[ AS ] table_alias
用于为 target_table 引用表的替代名称。USING <table_source>
指定根据 <merge_search_condition> 与 target_table 中的数据行进行匹配的数据源。 此匹配的结果指出了要由 MERGE 语句的 WHEN 子句采取的操作。 <table_source> 可以是一个远程表,或者是一个能够访问远程表的派生表。<table_source> 可以是一个派生表,它使用 Transact-SQL 表值构造函数通过指定多行来构造表。
[ AS ] table_alias
用于为 table_source 引用表的替代名称。有关此子句的语法和参数的详细信息,请参阅 FROM (Transact-SQL)。
ON <merge_search_condition>
指定联接 <table_source> 与 target_table 以确定匹配位置所要满足的条件。注意
请务必仅指定目标表中用于匹配目的的列。 也就是说,指定与源表中的对应列进行比较的目标表列。 请勿尝试通过在 ON 子句中筛选掉目标表中的行(如指定 AND NOT target_table.column_x = value)来提高查询性能。 这样做可能会返回意外和不正确的结果。
WHEN MATCHED THEN <merge_matched>
指定根据 <merge_matched> 子句更新或删除 *target_table 中所有与 <table_source> ON <merge_search_condition> 返回的行匹配、且满足其他所有搜索条件的行。MERGE 语句最多可以有两个 WHEN MATCHED 子句。 如果指定了两个子句,第一个子句必须随附 AND <search_condition> 子句。 对于任何给定行,只有在未应用第一个 WHEN MATCHED 子句时,才会应用第二个 WHEN MATCHED 子句。 如果有两个 WHEN MATCHED 子句,一个必须指定 UPDATE 操作,另一个必须指定 DELETE 操作。 如果在 <merge_matched> 子句中指定了 UPDATE,并且根据 <merge_search_condition><table_source> 中有多行与 target_table 中的一行匹配, SQL Server 便会返回错误。 MERGE 语句无法多次更新同一行,也无法更新和删除同一行。
WHEN NOT MATCHED [ BY TARGET ] THEN <merge_not_matched>
指定针对 <table_source> ON <merge_search_condition> 返回且不与 target_table 中的行匹配、但满足其他搜索条件(若有)的所有行,将一行插入 target_table 中。 要插入的值是由 <merge_not_matched> 子句指定的。 MERGE 语句只能有一个 WHEN NOT MATCHED [ BY TARGET ] 子句。WHEN NOT MATCHED BY SOURCE THEN <merge_matched>
指定根据 <merge_matched> 子句更新或删除 *target_table 中所有与 <table_source> ON <merge_search_condition> 返回的行不匹配而满足其他所有搜索条件的行。MERGE 语句最多可以有两个 WHEN NOT MATCHED BY SOURCE 子句。 如果指定了两个子句,第一个子句必须随附 AND <clause_search_condition> 子句。 对于任何给定行,只有在未应用第一个 WHEN NOT MATCHED BY SOURCE 子句时,才会应用第二个 WHEN NOT MATCHED BY SOURC 子句。 如果有两个 WHEN NOT MATCHED BY SOURCE 子句,那么其中的一个必须指定 UPDATE 操作,而另一个必须指定 DELETE 操作。 在 <clause_search_condition> 中只能引用目标表中的列。
如果 <table_source> 未返回任何行,无法访问源表中的列。 如果 <merge_matched> 子句中指定的更新或删除操作引用了源表中的列,则会返回错误 207(列名无效)。 例如,由于无法访问源表中的 WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1,因此 Col1 子句可能导致该语句失败。
AND <clause_search_condition>
指定任何有效的搜索条件。 有关详细信息,请参阅搜索条件 (Transact-SQL)。<table_hint_limited>
指定针对 MERGE 语句完成的每个插入、更新或删除操作,对目标表应用的一个或多个表提示。 需要有 WITH 关键字和括号。禁止使用 NOLOCK 和 READUNCOMMITTED。 有关表提示的详细信息,请参阅表提示 (Transact-SQL)。
对作为 INSERT 语句目标的表指定 TABLOCK 提示,与指定 TABLOCKX 提示的效果相同。 对表采用排他锁。 如果指定了 FORCESEEK,它会应用于与源表联接的目标表的隐式实例。
注意
指定带有 WHEN NOT MATCHED [ BY TARGET ] THEN INSERT 的 READPAST 可能会导致违反 UNIQUE 约束的 INSERT 操作。
INDEX ( index_val [,…n ] )
指定目标表上一个或多个索引的名称或 ID,以执行与源表的隐式联接。 有关详细信息,请参阅表提示 (Transact-SQL)。<output_clause>
针对 target_table 中不按照任何特定顺序更新、插入或删除的所有行返回一行。 $action 可在 output 子句中指定。 $action 是类型为 nvarchar(10) 的列,它返回每行(INSERT,UPDATE 或 DELETE)3 个值中的 1 个(具体视对相应行完成的操作而定)。 建议使用 OUTPUT 子句来查询或计算受 MERGE 影响的行。 有关该子句的参数和行为的详细信息,请参阅 OUTPUT 子句 (Transact-SQL)。OPTION ( <query_hint> [ ,…n ] )
指定优化器提示用于自定义数据库引擎处理语句的方式。 有关详细信息,请参阅 提示 (Transact-SQL) - 查询。<merge_matched>
指定更新或删除操作,应用于 target_table 中所有不与 <table_source> ON <merge_search_condition> 返回的行匹配、但满足其他所有搜索条件的行。UPDATE SET <set_clause>
指定目标表中要更新的列或变量名称的列表,以及用来更新它们的值。有关该子句的参数的详细信息,请参阅 UPDATE (Transact-SQL)。 不支持将变量设置为与列相同的值。
DELETE
指定删除与 target_table 中的行匹配的行。<merge_not_matched>
指定要插入到目标表中的值。( column_list )
要在其中插入数据的目标表中一个或多个列的列表。 必须使用单一部分名称来指定这些列,否则 MERGE 语句将失败。 必须用括号将 column_list 括起来,并且用逗号进行分隔。VALUES ( values_list)
返回要插入到目标表中的值的常量、变量或表达式的逗号分隔列表。 表达式不得包含 EXECUTE 语句。DEFAULT VALUES
强制插入的行包含为每个列定义的默认值。有关此子句的详细信息,请参阅 INSERT (Transact-SQL)。
<search_condition>
指定用于指定 <merge_search_condition> 或 <clause_search_condition> 的搜索条件。 有关此子句的参数的详细信息,请参阅搜索条件 (Transact-SQL)。graph search pattern
指定图匹配模式。 有关此子句参数的详细信息,请参阅 MATCH (Transact-SQL)。
4、备注
必须指定三个 MATCHED 子句中的至少一个子句,但可以按任何顺序指定。 无法在同一个 MATCHED 子句中多次更新一个变量。
MERGE 语句对目标表指定的任何插入、更新或删除操作受限于,在此语句中定义的任何约束,包括任何级联引用完整性约束。 如果 IGNORE_DUP_KEY 对目标表中的任何唯一索引都设置为 ON,MERGE 便会忽略此设置。
MERGE 语句需要一个分号 (