合并数据

使用 MERGE 语句来有条件地插入,更新或删除表或视图中的行。

可以使用 MERGE 语句从另一个表,派生表或任何其他表引用更新目标表。 此另一个表称为源表。 源表的最简单格式是值列表。

根据目标表中是否存在源表中的行, MERGE 语句可以插入新行,或者更新或删除匹配行。

MERGE 语句的最基本形式是插入新行 (如果不存在) 或更新 (如果存在)。 使用 MERGE 可避免尝试插入或更新,然后根据 SQLCODE 或 SQLSTATE 尝试其他选项。

在此示例中,您要为部门添加或替换行。 如果该部门尚不存在,那么将插入一行。 如果该部门存在,那么将更新该部门的信息。

MERGE INTO DEPARTMENT USING 
          (VALUES ('K22', 'BRANCH OFFICE K2', 'E01')) INSROW (DEPTNO, DEPTNAME, ADMRDEPT)
  ON DEPARTMENT.DEPTNO = INSROW.DEPTNO
  WHEN NOT MATCHED THEN
     INSERT VALUES(INSROW.DEPTNO, INSROW.DEPTNAME, NULL, INSROW.ADMRDEPT, NULL)
  WHEN MATCHED THEN 
     UPDATE SET DEPTNAME = INSROW.DEPTNAME, ADMRDEPT = INSROW.ADMRDEPT;

假设您有一个临时表是 EMP_PHOTO 表的副本。 在此表中,您为新员工添加了照片信息,并为现有员工更新了照片信息。 临时表仅包含更改,不包含未更改照片信息的行。

要将这些更新合并到主 EMP_PHOTO 表中,可以使用以下 MERGE 语句。

MERGE INTO EMP_PHOTO target USING TEMP_EMP_PHOTO source
     ON target.EMPNO = source.EMPNO
          AND target.PHOTO_FORMAT = source.PHOTO_FORMAT
WHEN NOT MATCHED THEN
   INSERT VALUES(EMPNO, PHOTO_FORMAT, PICTURE)
WHEN MATCHED THEN
   UPDATE SET PICTURE = source.PICTURE;

运行此语句时,将使用 EMPNO 和 PHOTO_FORMAT 列将目标表中的行与源表中的行进行比较。 这些是构成表的主键的列,因此它们保证唯一性。 源表中在目标表 (NOT MATCHING) 中没有匹配的 EMPNO 和 PHOTO_FORMAT 行的任何行都将执行 INSERT 操作。 在这种情况下,它会将新行插入到包含源表中的 EMPNO , PHOTO_FORMAT 和 PICTURE 值的目标表中。 源表中已在目标表 (成对) 中具有相应行的任何行都将使用源表中的 PICTURE 值更新目标表的行。

要使合并更复杂一点,让我们在 EMP_PHOTO 表中添加一列。

ALTER TABLE EMP_PHOTO ADD COLUMN LAST_CHANGED TIMESTAMP 
                            GENERATED BY DEFAULT FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP;

现在,让我们假设维护 TEMP_EMP_PHOTO 表的人员在临时表中有一些行已合并到 EMP_PHOTO 表的主副本中。 执行 MERGE 时,您不想再次更新相同的行,因为值未更改。 也有可能是别人用更近的图片更新了主控 EMP_PHOTO。

MERGE INTO EMP_PHOTO target USING TEMP_EMP_PHOTO source
     ON target.EMPNO = source.EMPNO
          AND target.PHOTO_FORMAT = source.PHOTO_FORMAT
WHEN NOT MATCHED THEN
   INSERT VALUES(EMPNO, PHOTO_FORMAT, PICTURE, LAST_CHANGED)
WHEN MATCHED AND target.LAST_CHANGED < source.LAST_CHANGED THEN
   UPDATE SET PICTURE = source.PICTURE,
              LAST_CHANGED = source.LAST_CHANGED;

此语句具有添加到成对子句的额外条件。 添加 LAST_CHANGED 列的比较将阻止使用时间戳记早于当前主时间戳记的照片来更新主 EMP_PHOTO 表。