使用 MERGE 语句,通过在单个 SQL 语句内综合 UPDATE 或 DELETE 操作与 INSERT 操作,来将数据从源表转移到目标表内。您还可使用此语句来将源表与目标表合并,然后对目标表仅执行 UPDATE 操作,仅执行 DELETE 操作,或仅执行 INSERT 操作。
MERGE 语句以 GBase 8s 扩展支持 SQL 的 ANSI/ISO 标准。
元素 | 描述 | 限制 | 语法 |
---|---|---|---|
alias | 您为 target 或 source 表对象在此声明的临时名称 | 源别名与目标别名必须不同。如果有可能含糊,则在 alias 之前加上 AS 关键字。 | 标识符 |
column | 向其内插入源数据的目标对象中的列 | 在目标对象中必须存在 | 标识符 |
condition | 适用于 source 与 target 表的结合中的行的 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 子句。
如果未指定 Delete 子句,未指定 Update 子句,且未指定 Insert 子句,则 MERGE 语句失败并提示错误。
然而,单个 MERGE 语句仅可有这三个影响中的两个,因为 Delete 子句与 Update 子句是互斥的。
在高可用性集群配置中,您可从主服务器或从可更新的辅助服务器发出 MERGE 语句。
您可在 MERGE 关键字之后,可选地指定一个或多个查询优化器命令,诸如访问方法命令、结合顺序命令和结合方法命令来指定源表与目标表如何结合。在 MERGE 语句中,诸如 EXPLAIN 和 AVOID_EXECUTE 这样的面向目标的命令也有效。
在 MERGE 语句内,子查询还可包括优化器命令来控制该执行计划的其他方面。在 MERGE 语句中的下列上下文中子查询是有效的:
然而,如果包括引用目标表的子查询,则 MERGE 语句失败并报错。
在支持外部命令的数据库中,查询优化器还可对源与目标表的外部结合应用外部命令,或对 MERGE 语句内的子查询。
对与条件相匹配的行上的 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 语句。
如果以 ON DELETE CASCADE 关键字定义了目标表上的引用约束,则 MERGE 语句的 DELETE 子句还对目标表的孩子表的行执行级联删除。
然而,如果启用了的引用约束已在目标和源表之间建立了父子关系,则 Delete 合并失败。MERGE 语句不可在其源表上执行级联删除。要获取更多信息,请参阅主题 表有级联删除时对 DELETE 的限制。
要在目标表上启用违反表和诊断表,SET Database Object Mode 语句必须设置约束或目标表的唯一索引为 ENABLED 或 FILTERING 模式。要了解更多信息,请参阅主题 与 SET Database Object Mode 语句的关系 和 SET Database Object Mode 语句。
目标对象可为在其上定义 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 安全策略保护的表。