处理重复的行

在执行 MERGE 时,目标表中的同一行不可被更新或被删除一次以上。在执行了 MERGE 语句之前,请勿尝试更新或删除尚未存在的目标中的任何行。即,没有同一 MERGE 语句插入到目标内的行的更新或删除。

下列 MERGE 语句的示例使用事务表 new_sale 作为源表,从其来在事实表中插入或更新行。在此样例中的结合条件测试 new_sale.cust_id 列值与 sale.cust_id 列值是否相匹配。
MERGE INTO sale USING new_sale AS n 
   ON sale.cust_id = n.cust_id
   WHEN MATCHED THEN UPDATE 
      SET sale.salecount = sale.salecount + n.salecount
   WHEN NOT MATCHED THEN INSERT (cust_id, salecount) 
      VALUES (n.cust_id, n.salecount);
要执行此 MERGE 语句,数据库服务器结合目标表和源表,并应用指定的相等条件来处理结合的结果:
对于先前示例中的 MERGE 语句,假设 sale 目标包含两条记录,而 new_sale 源表包含三条记录。
表 1. “sale”表中的记录
cust_id sale_count
Tom 129
Julie 230
表 2. “new_sale”表中的记录
cust_id sale_count
Tom 20
Julie 3
Julie 10

当通过指定表达式 sale.cust_id = new_sale.cust_id 作为匹配条件将 new_sale 合并至 sale 内时,MERGE 语句返回错误,因为它尝试超过一次更新 sale 目标表中的记录之一。

分布式 MERGE 操作中的数据类型

如果源表或视图(或任何在源查询中引用的表对象)指定在 GBase 8s 实例的数据库中的表对象, 而不是管理目标表的数据库的本地实例,则 MERGE 语句仅可访问远程数据库中的下列数据类型的列:
  • 非 opaque 的内建的数据类型
  • BOOLEAN
  • LVARCHAR
  • 非 opaque 的内建的数据类型的 DISTINCT
  • BOOLEAN 的 DISTINCT
  • LVARCHAR 的 DISTINCT
  • 出现在此列表中的任何 DISTINCT 数据类型的 DISTINCT。

跨服务器的分布式 MERGE 操作可支持这些 DISTINCT 类型,仅当将 DISTINCT 类型显式地强制转型为内建的类型,且在每一参与的数据库中以完全相同的方式定义所有 DISTINCT 类型、其数据类型层级及其强制转型。要获取关于 GBase 8s 在跨服务器 DML 操作中支持的数据类型的附加信息,请参阅 跨服务器事务中的数据类型

MERGE 不可访问另一 GBase 8s 实例的数据库,除非两个数据库实例都支持 TCP/IP 或 IPCSTR 连接,这定义在它们的 DBSERVERNAME 或 DBSERVERALIASES 配置参数中,以及在 sqlhosts 文件或 SQLHOSTS 注册子键中。此连接类型的要求适用于 GBase 8s 实例之间的任何通信,即使两个数据库服务器位于同一台计算机上。

然而,访问在本地 GBase 8s 实例的其他数据库中的表对象的 MERGE 操作,可访问前述列表中任何跨服务器的数据类型以及这些附加的数据类型:
  • 大部分内建的 opaque 数据类型,如 跨数据库事务中的数据类型 中所列
  • 同一内建的 opaque 类型的 DISTINCT
  • 在前面两行中的任何数据类型的 DISTINCT
  • 显式地强制转型为内建的数据类型的 opaque 用户定义的数据类型(UDT)。

MERGE 语句还支持通用客户端 API 中的 “分布式关系数据库架构”™(DRDA®)协议。对于MERGE 可从远程数据库通过 DRDA 协议返回的 GBase 8s 数据类型,要查看 DRDA 所支持(以及不支持)的 GBase 8s 数据类型的列表,请参阅 GBase 8s 管理员指南