データのマージ

MERGE ステートメントを使用して、表またはビューの行を条件に基づいて挿入、更新、または削除します。

MERGE ステートメントを使用すると、ターゲット表を別の表、派生表、または他のいずれかの表参照に基づいて更新できます。 この別の表のことを、ソース表と呼びます。 最も簡単な形式のソース表は、値のリストです。

MERGE ステートメントは、ソース表の行がターゲット表に存在するかどうかに基づいて、 新規に行を挿入したり、一致する行を更新または削除したりできます。

MERGE ステートメントの最も基本的な形式は、行がまだ存在しない場合にはそれを新規に挿入し、行が存在する場合にはそれを更新するというものです。 SQLCODE または SQLSTATE に基づいて挿入または更新を試行した後に他のオプションを試行する代わりに、 MERGE ステートメントを使用すると適切な操作が実行されます。

この例では、ある部門において 1 行を追加または置換します。 その部門がまだ存在しない場合は、行が挿入されます。 その部門が存在する場合、部門の情報が更新されます。

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, INSROW.ADMRDEPT)
  WHEN MATCHED THEN 
     UPDATE SET DEPTNAME = INSROW.DEPTNAME, ADMRDEPT = INSROW.ASMRDEPT

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 列を使用してソース表の行と比較されます。 これらは表の主キーを形成する列であるので、固有性が保証されます。 ソース表にある行のうち、一致する EMPNO および PHOTO_FORMAT 行がターゲット表に存在しないもの (NOT MATCHED) については、INSERT 操作が実行されます。 この場合、ソース表の EMPNO、PHOTO_FORMAT、および PICTURE の各値が入った新しい行がターゲット表に挿入されます。 ソース表にある行のうち、対応する行がターゲット表に既に存在するもの (MATCHED) については、ターゲット表の行がソース表の PICTURE 値で更新されます。

マージを少し複雑にするために、1 列を 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

このステートメントでは、MATCHED 節に追加の条件が追加されています。 LAST_CHANGED 列の比較を追加することにより、現在のマスターのタイム・スタンプより古いタイム・スタンプを持つ写真によってマスター EMP_PHOTO 表が更新されることを防止します。