MERGE 语句

使用 MERGE 语句,通过在单个 SQL 语句内综合 UPDATE 或 DELETE 操作与 INSERT 操作,来将数据从源表转移到目标表内。您还可使用此语句来将源表与目标表合并,然后对目标表仅执行 UPDATE 操作,仅执行 DELETE 操作,或仅执行 INSERT 操作。

MERGE 语句以 GBase 8s 扩展支持 SQL 的 ANSI/ISO 标准。

语法

Update 子句
Delete 子句
Insert 子句
元素 描述 限制 语法
alias 您为 targetsource 表对象在此声明的临时名称 源别名与目标别名必须不同。如果有可能含糊,则在 alias 之前加上 AS 关键字。 标识符
column 向其内插入源数据的目标对象中的列 在目标对象中必须存在 标识符
condition 适用于 sourcetarget 表的结合中的行的 Boolean 条件 可引用 source target 对象中的数据值 条件
derived_column 如果该源对象为派生的表,则您在此声明其名称 SET 和 VALUES 子句可引用此名称。 标识符
directive 查询优化器命令 命令必须有效。 优化程序伪指令
source_table, source_view, source_subquery 包含要被重定位的数据的表(或查询的结果) 对象必须存在。另请参阅 对 MERGE 的源表和目标表的限制 数据库对象名; SELECT 语句
target_table, target_view, target_synonym 表的名称或同义词,或向其中插入、更新或删除数据的可更新的视图 请参阅 对 MERGE 的源表和目标表的限制 数据库对象名

用法

GBase 8s 的 MERGE 语句是数据操纵语言(DML)语句,将源表对象与目标表或视图结合。您在 ON 关键字之后指定的 condition 决定在目标上的 UPDATE 或 DELETE 操作中使用源对象的哪一行,以及在目标上的 INSERT 操作中使用哪一行。MERGE 语句不更改源对象。

条件必须后跟 Delete 或 Update 子句的 WHEN MATCHED THEN 关键字,或后跟 Insert 子句的 WHEN NOT MATCHED THEN 关键字,或后跟 Update(或 Delete)以及 Insert 子句。

  • 如果您指定 Update 和 Insert 两个子句,则 MERGE 语句可在目标对象上执行 INSERT 和 UPDATE 两个操作。
  • 如果您指定 Delete 和 Insert 两个子句,则 MERGE 语句可在目标对象上执行 INSERT 和 DELETE 两个操作。
  • 如果您未指定 Insert 子句,则不执行 INSERT 操作,但 Update 子句必须在满足该条件的源行的目标对象上指定 UPDATE 操作(抑或 Delete 子句必须指定 DELETE 操作)。
  • 如果您未指定 Update 子句且未指定 Delete 子句,则不执行 UPDATE 或 DELETE 操作,但 Insert 子句必须为不匹配该对象的源行指定目标对象上的 INSERT 操作。

如果未指定 Delete 子句,未指定 Update 子句,且未指定 Insert 子句,则 MERGE 语句失败并提示错误。

MERGE 语句可对目标对象产生下列影响:
  • 如果包括 Update 子句,则 MERGE 语句根据 SET 子句的规范,以源表中该条件取值为真的行的数据更新目标表或视图中的行。
  • 如果包括 Delete 子句,则 MERGE 语句从目标表或视图删除该条件取值为真的行。
  • 如果包括 Insert 子句,则 MERGE 语句根据 VALUES 子句的规范,以源表中该条件取值为假的行数据,向目标表或视图内插入新行。

然而,单个 MERGE 语句仅可有这三个影响中的两个,因为 Delete 子句与 Update 子句是互斥的。

对于大型表上的操作,请确保在您的系统上可获得这些资源:
  • 足够数量的锁
  • 用于中间的结合结果的足够的临时 dbspace 存储
  • 用于 MERGE 语句的结果的充足的 dbspace 存储。

在高可用性集群配置中,您可从主服务器或从可更新的辅助服务器发出 MERGE 语句。

优化器命令和子查询

您可在 MERGE 关键字之后,可选地指定一个或多个查询优化器命令,诸如访问方法命令、结合顺序命令和结合方法命令来指定源表与目标表如何结合。在 MERGE 语句中,诸如 EXPLAIN 和 AVOID_EXECUTE 这样的面向目标的命令也有效。

在 MERGE 语句内,子查询还可包括优化器命令来控制该执行计划的其他方面。在 MERGE 语句中的下列上下文中子查询是有效的:

然而,如果包括引用目标表的子查询,则 MERGE 语句失败并报错。

在支持外部命令的数据库中,查询优化器还可对源与目标表的外部结合应用外部命令,或对 MERGE 语句内的子查询。

ON 条件

跟在 ON 关键字之后的 condition 为源和目标表对象指定结合过滤器。 基于目标和源表的外部结合,此 ON 子句过滤器确定 MERGE 语句中匹配的行和不匹配的行。
  • 如果 MERGE 语句包括 Update 子句,且 ON 子句条件取值为真,则在目标中更新相应的行。
  • 如果 MERGE 语句包括 Delete 子句,且 ON 子句条件取值为真,则从目标删除相应的行。
  • 如果 MERGE 语句包括 Insert 子句,且 ON 子句条件取值为假,则将相应的源行插入到目标内。

对与条件相匹配的行上的 MERGE 语句的 Update 操作,服从该 SET 子句的 UPDATE 语句规则。要获取在目标表中指定被更新的值的语法的详细信息,请参阅 SET 子句

对与条件相匹配的行上的 MERGE 语句的 Delete 操作,服从 DELETE 语句规则。要了解从目标表删除值的详细信息,请参阅 使用 WHERE 关键字指定条件

对与条件不相匹配的行上的 Insert 操作服从 VALUES 子句的 INSERT 语句规则。要了解将值插入到目标表中的语法的详细信息,请参阅 VALUES 子句

错误处理

如果在 MERGE 语句正在执行过程中发生错误,则回滚整个语句。

对于支持事务日志记录的数据库,您可包括错误处理逻辑,包括包括定义一个或多个保存点的 MERGE 语句的事务中的 ROLLBACK TO SAVEPOINT 语句在该事务部分回滚到保存点之后,在目标表中保持 MERGE 语句的 INSERT、DELETE 或 UPDATE 操作的影响,如果在该事务的保存点级的语句的文本顺序中,该 MERGE 语句在保存点的前面的话。如果在该事务内,该 MERGE 语句跟在指定的保存点之后,则回滚 MERGE 的影响。

在符合 ANSI 的数据库中,数据操纵语言(DML)语句通常在事务之中。这些数据库不支持事务之外的 MERGE 语句。

约束检查

在 MERGE 操作中,强制对目标对象启用数据完整性约束。
  • 如果检查模式设置为 DEFERRED,则直到提交该事务之后,才检查这些约束。
  • 如果目标表的约束检查模式设置为 IMMEDIATE,则在所有 UPDATE(或 DELETE)和 INSERT 操作完成之后,检查唯一约束和引用约束。在 UPDATE、DELETE 和 INSERT 操作期间,检查 NOT NULL 和检查约束。
要获取关于设置约束检查模式的信息,请参阅主题 SET Transaction Mode 语句

如果以 ON DELETE CASCADE 关键字定义了目标表上的引用约束,则 MERGE 语句的 DELETE 子句还对目标表的孩子表的行执行级联删除。

然而,如果启用了的引用约束已在目标和源表之间建立了父子关系,则 Delete 合并失败。MERGE 语句不可在其源表上执行级联删除。要获取更多信息,请参阅主题 表有级联删除时对 DELETE 的限制

如果 START VIOLATIONS 语句已在目标表上定义了活动的违反表,则 MERGE 可对目标、违反和诊断表有下列影响:
  • 或删除或更新与结合条件相匹配的目标表中的符合的行。
  • 目标表还收到 MERGE 成功地插入的符合的不相匹配的行。
  • 违反表收到不符合的行。
  • 诊断表收到关于不符合的行不能满足约束的原因的信息,以及对目标表的 MERGE 操作期间的唯一索引的信息。

要在目标表上启用违反表和诊断表,SET Database Object Mode 语句必须设置约束或目标表的唯一索引为 ENABLED 或 FILTERING 模式。要了解更多信息,请参阅主题 与 SET Database Object Mode 语句的关系SET Database Object Mode 语句

使用带有触发器的 MERGE 语句

目标对象可为在其上定义 Update、Delete 或 Insert 触发器的表。如果在目标表上 Update 触发器和 Insert 触发器(或 Delete 触发器和 Insert 触发器)都启用,则 MERGE 作为两个触发器的触发事件,如果 MERGE 语句在目标上执行 UPDATE(或 DELETE)和 INSERT 操作的话。

如果 MERGE 语句包括激活 Update(或 Delete)和 Insert 触发器的操作,则当 MERGE 操作启动时,两个触发器的 BEFORE 触发器活动都执行。类似地,在 MERGE 操作的结尾,两个触发器的 AFTER 触发器活动都执行。每处理一行,都激活 FOR EACH ROW 触发器活动。

恰如对任何 DML 语句那样,数据库服务器将同一 MERGE 语句激活的所有触发器视同一个单个触发器,且结果触发器活动是合并的活动列表。控制一个触发器活动的所有规则适用于作为一个列表的合并的列表,且对这两个原始触发器一视同仁。要获取更多信息,请参阅 多个触发器的操作

然而,目标对象不可为在其上定义启用的 INSTEAD OF 触发器的视图。在您可使用那个视图作为 MERGE 语句的目标之前,您必须禁用或删除该 INSTEAD OF 触发器。

在触发器的定义中,不可直接指定 MERGE 语句作为触发器活动。然而,在触发的活动中调用的 SPL 触发器例程可发出 MERGE 语句。

安全策略和安全审计

如果源对象或其任何列被基于标签的访问控制(LBAC)安全策略所保护,则发出该 MERGE 语句的用户必须有安全标签(或必须持有安全策略豁免),提供其足以在 MERGE 操作中读取该源表的凭证。

如果目标对象或其任何列被基于标签的安全策略所保护,则发出 MERGE 语句的用户必须有安全标签(或持有安全策略豁免),提供其足以在 SET 子句或 VALUES 子句指定的目标对象列中写的凭证,或足以从包括受保护的数据的目标删除行的凭证。

如果源和目标表都受到保护,则它们必须受到同一安全策略的保护。MERGE 语句不可结合那些受不同的 LBAC 安全策略保护的表。

在使用安全审计功能来记录活动的 GBase 8s 实例上,可能潜在地修改或显示数据或审计配置,在对 MERGE 语句的审计跟踪中未定义特定的审计事件助记符:
  • Delete 子句指定的活动记录为 DELETE 事件。
  • Insert 子句指定的活动记录为 INSERT 事件。
  • Update 子句指定的活动记录为 UPDATE 事件。
1 请参阅 VALUES 子句
2 请参阅 SET 子句
3 使用此路径不超过一次