MERGE ステートメント

MERGE ステートメントは、 ソース (表参照の結果) からのデータを使ってターゲット (表またはビュー、 あるいは全選択の基礎表またはビュー) を更新します。

ターゲット内にあるソースと一致する行を削除または更新するよう指定でき、 ターゲットに存在しない行を挿入することができます。 ビュー内の行を更新、削除、または挿入すると、 ビューの元になっている表の行が更新、削除、または挿入されます。

呼び出し

このステートメントは、アプリケーション・プログラムに組み込んだり、動的 SQL ステートメントを使用して発行したりすることができます。 このステートメントは、動的に作成できる実行可能ステートメントです。

許可

ステートメントの許可 ID によって保持されている特権には、少なくとも以下のいずれかの権限が含まれていなければなりません。
  • 挿入操作が指定されている場合は、表またはビューに対する INSERT 特権、または表またはビューを含むスキーマに対する INSERTIN 特権。削除操作が指定されている場合は、表またはビューに対する DELETE 特権または表またはビューを含むスキーマに対する DELETEIN 特権。更新操作が指定されている場合は、以下のいずれかです。
    • 表またはビューに対する UPDATE 特権
    • 更新されるそれぞれの列に対する UPDATE 特権
    • 表またはビューが含まれるスキーマに対する UPDATEIN 特権
  • 表に対する CONTROL 特権
  • 表またはビューが含まれるスキーマに対する DATAACCESS 権限
  • DATAACCESS 権限
このステートメントの許可 ID が持つ特権には、少なくとも次の権限のいずれかも含まれている必要があります。
  • table-reference で指定されたすべての表またはビューに対する SELECT 特権
  • table-reference で指定された表またはビューが含まれるスキーマに対する SELECTIN 特権
  • table-reference で指定された表またはビューに対する CONTROL 特権
  • table-reference で指定された表またはビューが含まれるスキーマに対する DATAACCESS 権限
  • DATAACCESS 権限
search-conditioninsert-operation、または assignment-clause が副照会を持つ場合、 このステートメントの許可 ID が持つ特権には、少なくとも次の権限のいずれかも含まれている必要があります。
  • 副照会で指定されたすべての表またはビューに対する SELECT 特権
  • 副照会で指定された表またはビューが含まれるスキーマに対する SELECTIN 特権
  • 副照会で指定された表またはビューに対する CONTROL 特権
  • 副照会で指定された表またはビューが含まれるスキーマに対する DATAACCESS 権限
  • DATAACCESS 権限
割り当て式に row-fullselect (行全選択) を含める場合には、ステートメントの許可 ID に、参照される表、ビュー、またはニックネームのそれぞれに対して、以下の権限が少なくとも 1 つ含まれている必要があります。
  • SELECT 特権
  • 参照された表、ビュー、またはニックネームが含まれるスキーマに対する SELECTIN 特権
  • CONTROL 特権
  • 参照された表、ビュー、またはニックネームが含まれるスキーマに対する DATAACCESS 権限
  • DATAACCESS 権限

関数を参照する式が指定されている場合、 特権セットにはその関数を実行するのに必要な権限が含まれていなければなりません。

構文

Read syntax diagramSkip visual syntax diagramMERGE INTO table-nameview-name(WITH,common-table-expressionfullselect) correlation-clauseUSINGtable-referenceONsearch-conditionWHENmatching-conditionTHENmodification-operationsignal-statementELSE IGNOREWITHRRRSCSUR
correlation-clause
Read syntax diagramSkip visual syntax diagramAScorrelation-name (,column-name)
matching-condition
Read syntax diagramSkip visual syntax diagramNOTMATCHED ANDsearch-condition
modification-operation
Read syntax diagramSkip visual syntax diagramupdate-operationdelete-operationinsert-operation
update-operation
Read syntax diagramSkip visual syntax diagramUPDATE period-clause SETassignment-clause
assignment-clause
Read syntax diagramSkip visual syntax diagram,column-name = expressionDEFAULTNULL(,column-name) = (,expression1DEFAULTNULLrow-fullselect2)
delete-operation
Read syntax diagramSkip visual syntax diagramDELETE period-clause
insert-operation
Read syntax diagramSkip visual syntax diagramINSERT (,column-name) VALUES expressionDEFAULTNULL(,expressionDEFAULTNULL)
period-clause
Read syntax diagramSkip visual syntax diagramFOR PORTION OF BUSINESS_TIME FROMvalue1TOvalue2
Notes:
  • 1 The number of expressions, NULLs, and DEFAULTs must match the number of column names.
  • 2 The number of columns in the select list must match the number of column names.

説明

table-nameview-name、または (fullselect)
マージの更新、削除、または挿入操作のターゲットを識別します。 この名前は、現在のサーバーに存在する表またはビューを識別する必要があります。 ただし、カタログ表、システムで保守されているマテリアライズ照会表、 カタログ表のビュー、読み取り専用のビューを参照することはできません。さらに、 NOT DETERMINISTIC または EXTERNAL ACTION を使って定義されている副照会またはルーチンを参照する WHERE 節を直接的または間接的に含むようなビューを参照することもできません (SQLSTATE 42807)。

マージ操作のターゲットが全選択である場合、全選択は、 「更新可能ビュー」「削除可能ビュー」、または 「挿入可能ビュー」 で定義されたとおりに更新可能、削除可能、または挿入可能でなければなりません。CREATE VIEW ステートメントの説明にある項目に注意してください。

マージ操作のターゲットが UNION ALL ビューまたは全選択である場合、 更新操作および削除操作に period-clause は使用できません。

ニックネーム (リモート・フェデレーテッド表への参照) をターゲット表として使用することはできません。

correlation-clause
search-condition 内や assignment-clause の右側で使用して、 表、ビュー、または全選択を指定できます。 correlation-clause の説明については、『副選択』の説明の table-reference を参照してください。
USING 表参照
ターゲットにマージされる結果表として、 行のセットを指定します。 結果表が空の場合、警告が戻されます (SQLSTATE 02000)。
ON 検索条件
論理的には、右結合は ON search-condition を使用してターゲット表と table-reference の間で行われます。 結合結果表の行のうち検索条件が真である行については、指定した更新操作または削除操作が実行されます。 結合結果表の行のうち検索条件の結果が真でない行については、指定した挿入操作が実行されます。
search-condition には、以下の制限があります (特に注記のない限り SQLSTATE 42972)。
  • 副照会 (スカラーなど) を入れることはできない
  • 参照値がオブジェクト ID 列以外の場合、間接参照操作または DEREF 関数を組み込むことはできない
  • SQL 関数を組み入れることはできない
  • XMLQUERY または XMLEXISTS 式を組み入れることはできない
  • search-condition の式で参照されるどの列も、ターゲット表、ビュー、または table-reference の列でなければならない。
  • 全外部結合の join-condition の式で参照される関数は、決定論的なものでなければならず、外部アクションがあってはならない。
  • 集約関数を含めることはできません (SQLSTATE 42903)

table-reference のどの行についても search-condition が偽または不明の場合は、警告が戻されます (SQLSTATE 02000)。

WHEN マッチング条件
modification-operation または signal-statement が実行される条件を指定します。 それぞれの matching-condition は、 指定された順序で評価されます。 matching-condition が真と評価された行は、 後続の一致条件では無視されます。
MATCHED
ON 検索条件が真である行に対して実行される操作を示します。 THEN の後には、UPDATE、DELETE、 または signal-statement のみを指定できます。
AND 検索条件
ON 検索条件に一致する行に対して THEN 後の操作を実行するための、 さらに適用される追加の検索条件を指定します。
NOT MATCHED
ON 検索条件が偽または不明である行に対して実行される操作を示します。 THEN の後には、INSERT または signal-statement のみを指定できます。
AND 検索条件
ON 検索条件に一致しなかった行に対して THEN 後の操作を実行するための、 さらに適用される追加の検索条件を指定します。 この検索条件は、ON 検索条件に一致しなかった行にのみ適用されます。AND 検索条件 がターゲット表の列を参照する場合、構文エラー (SQL0206N) が戻される可能性があります。
THEN 変更-操作
matching-condition が真と評価された場合に実行される操作を指定します。
更新操作
matching-condition が真と評価された行に対して実行される更新操作を指定します。
UPDATE
更新操作を指定します。
period-clause
これを指定すると、期間節が MERGE ステートメントの更新操作に適用されます。 更新操作のコンテキストで指定した期間節の影響について詳しくは、UPDATE ステートメントのトピックを参照してください。
SET
この後に、列名への値の割り当てを指定します。
割り当て文節
列更新のリストを指定します。
column-name
更新する列を指定します。 column-name は指定された表またはビューの列を識別する必要がありますが、 スカラー関数、定数、 または式から得られたビュー列を識別することはできません。 同じ列を複数回指定することはできません (SQLSTATE 42701)。

1 つのビュー列から得られた 2 つのビュー列を更新するとき、 両方の列を 1 つの MERGE ステートメントで更新することはできません (SQLSTATE 42701)。

expression
列の新しい値を指定します。 スカラー fullselect で使用される場合を除き、expression に集約関数を含めることはできません (SQLSTATE 42903)。

expression には、 table-name または view-name の列への参照を含めることができます。 更新対象の行ごとに、式の中のそのような列の値は、行の更新前のその行の列の値になります。

expression がソース表の単一の列への参照である場合、ソース表の列の値は、拡張標識変数の値で指定された可能性があります。 そのような標識変数は、assignment-clause の対応するターゲット列に影響を与えます。

expression が単一のホスト変数、または明示的にキャストされるホスト変数である場合、拡張標識変数に対応する標識変数をホスト変数に含めることができます。

拡張標識変数が使用可能であり、以下の文のいずれかが当てはまる場合には、デフォルト (-5) または未割り当て (-7) の拡張標識変数の値を使用しないでください (SQLSTATE 22539)。

  • 式が明示的キャストによる単一ホスト変数より複雑な場合
  • ターゲット列のデータ・タイプが構造化タイプである
DEFAULT
列に割り当てられるデフォルト値。 デフォルト値を持つ列に関してのみ、DEFAULT を指定できます。 データ・タイプのデフォルト値については、CREATE TABLE ステートメントの DEFAULT 節の説明を参照してください。

GENERATED ALWAYS として定義された列に関しては、 DEFAULT を指定する必要があります。 GENERATED BY DEFAULT として定義された列に関しては、 有効な値を指定することができます。

ヌル
列の新しい値として NULL 値を指定します。 NULL は、NULL 可能列にのみ指定できます (SQLSTATE 23502)。
行全選択
単一行を返す全選択を指定します。 結果列の値は、対応する各 column-name に割り当てられます。 全選択が行を返さなければ各列に NULL 値が割り当てられ、更新される列が NULL 可能でない場合はエラーが発生します。 結果に複数の行がある場合も、エラーが発生します。

row-fullselect には、MERGE ステートメントのターゲット表の列に対する参照を含めることができます。 更新対象の行ごとに、式の中のそのような列の値は、行の更新前のその行の列の値になります。 結果に行が複数ある場合、エラーが返されます (SQLSTATE 21000)。

削除操作
matching-condition が真と評価された行に対して実行される削除操作を指定します。
DELETE
削除操作を指定します。
period-clause
これを指定すると、期間節が MERGE ステートメントの削除操作に適用されます。 削除操作のコンテキストで指定した期間節の影響について詳しくは、DELETE ステートメントのトピックを参照してください。
挿入操作
matching-condition が真と評価された行に対して実行される挿入操作を指定します。
INSERT
挿入操作に使われる、 列名と行値の式からなるリストを指定します。

行値の式における行の値の数は、 挿入列リストにおける名前の数と同じでなければなりません。 最初の値はリストの最初の列に挿入され、2 番目の値は 2 番目の列に挿入されます。 以下同様です。

(列名)。
挿入値が提供される列を指定します。 それぞれの名前は、表またはビューの列を識別する必要があります。 同じ列を複数回指定することはできません (SQLSTATE 42701)。 挿入値を受け入れることのできないビューの列を指定することはできません。 以下のようなビュー列には、値を挿入できません。
  • 定数、式、またはスカラー関数から得られる列。
  • そのビューの他の列と同じ基本表の列から得られる列。

操作の対象となるビューにこのような列がある場合は、 列名のリストを指定する必要があり、 そのリストに上記の列を指定してはなりません。

列のリストを省略すると、(暗黙的な非表示として定義されていない) 表またはビューのすべての列を左から右に指定したリストが暗黙に指定されます。 このリストはステートメントが準備される時点で確立されます。 したがって、ステートメントの準備後に表に追加された列は含まれません。

VALUES
挿入する 1 つ以上の行の値を、この後に指定します。
expression
列名を含まない任意の式 (SQLSTATE 42703)。

expression がソース表の単一の列への参照である場合、ソース表の列の値は、拡張標識変数の値で指定された可能性があります。 そのような標識変数は、insert-operation の対応するターゲット列に影響を与えます。

expression が単一のホスト変数、または明示的にキャストされるホスト変数である場合、拡張標識変数に対応する標識変数 (ホスト構造の場合は標識配列) をホスト変数に含めることができます。

拡張標識変数が使用可能であり、以下の文のいずれかが当てはまる場合には、デフォルト (-5) または未割り当て (-7) の拡張標識変数の値を使用しないでください (SQLSTATE 22539)。

  • 式が明示的キャストによる単一ホスト変数より複雑な場合
  • ターゲット列のデータ・タイプが構造化タイプである
DEFAULT
列に割り当てられるデフォルト値。 デフォルト値を持つ列に関してのみ、DEFAULT を指定できます。 データ・タイプのデフォルト値については、CREATE TABLE ステートメントの DEFAULT 節の説明を参照してください。

GENERATED ALWAYS として定義された列に関しては、 DEFAULT を指定する必要があります。 GENERATED BY DEFAULT として定義された列に関しては、 有効な値を指定することができます。

ヌル
列の値として NULL 値を指定します。 NULL は、NULL 可能列にのみ指定できます (SQLSTATE 23502)。
シグナル・ステートメント
matching-condition が真と評価された場合にエラーを戻すために実行される SIGNAL ステートメントを指定します。
ELSE IGNORE
どの matching-condition も真と評価されない場合に、 行に対してアクションが実行されないことを指定します。 table-reference のすべての行が無視された場合は、警告が戻されます (SQLSTATE 02000)。
WITH
MERGE ステートメントが実行される分離レベルを指定します。
RR
反復可能読み取り
RS
読み取り固定
CS
カーソル固定
UR
非コミット読み取り
ステートメントのデフォルト分離レベルは、ステートメントがバインドされている パッケージの分離レベルです。

ルール

  • 複数の modification-operation (UPDATE SET、DELETE 、 または insert-operation) あるいは signal-statement を、 単一の MERGE ステートメントの中で指定できます。
  • ターゲット内の各行は、一度だけ操作できます。 ターゲット内の各行は、 table-reference の結果表のただ 1 つの行とのみ MATCHED として識別されます (SQLSTATE 21506)。 ネストした SQL 操作 (RI、 または INSTEAD OF トリガーを除くトリガー) では、 ターゲット表 (または同じ表階層内の表) を UPDATE、DELETE、INSERT、 または MERGE ステートメントのターゲットとして指定することはできません (SQLSTATE 27000)。
  • セキュリティー・ポリシー: 識別されたターゲット表または識別されたターゲット・ビューの基本表がセキュリティー・ポリシーによって保護されている場合、SESSION 許可 ID は以下のタイプのアクセスを許可するラベル・ベースのアクセス制御 (LBAC) 信用証明情報を持つ必要があります。
    • 更新操作の場合:
      • 更新対象となる保護されたすべての列に対する書き込みアクセス (SQLSTATE 42512)
      • RESTRICT NOT AUTHORIZED WRITE SECURITY LABEL オプションを使って生成されたセキュリティー・ポリシーに関して DB2SECURITYLABEL 列に明示的に与えられる値に対する書き込みアクセス (SQLSTATE 23523)
      • 更新対象となるすべての行に対する読み取りおよび書き込みアクセス (SQLSTATE 42519)

      さらに、DB2SECURITYLABEL 列に暗黙的な値が使用される場合には、セキュリティー・ポリシーの書き込みアクセスに関するセキュリティー・ラベルもまた、セッション許可 ID に付与されている必要があります (SQLSTATE 23523)。このような暗黙的な値は、以下の場合に使用される可能性があります。

      • DB2SECURITYLABEL 列が更新される列のリストに含まれていない (そのため、 SESSION 許可 ID の書き込みアクセスのセキュリティー・ラベルに暗黙的に更新される)
      • DB2SECURITYLABEL 列の値が明示的に提供されているが、セッション許可 ID がその値に対する書き込みアクセスを持たず、OVERRIDE NOT AUTHORIZED WRITE SECURITY LABEL オプションを使ってセキュリティー・ポリシーが生成されている
    • 削除操作の場合:
      • すべての保護された列に対する書き込みアクセス (SQLSTATE 42512)
      • 削除のために選択されたすべての行に対する読み取りおよび書き込みアクセス (SQLSTATE 42519)
    • 挿入操作の場合:
      • データ値が明示的に提供される、保護されたすべての列に対する書き込みアクセス (SQLSTATE 42512)
      • RESTRICT NOT AUTHORIZED WRITE SECURITY LABEL オプションを使って生成されたセキュリティー・ポリシーに関して DB2SECURITYLABEL 列に明示的に与えられる値に対する書き込みアクセス (SQLSTATE 23523)

      さらに、DB2SECURITYLABEL 列に暗黙的な値が使用される場合には、セキュリティー・ポリシーの書き込みアクセスに関するセキュリティー・ラベルもまた、セッション許可 ID に付与されている必要があります (SQLSTATE 23523)。このような暗黙的な値は、以下の場合に使用される可能性があります。

      • DB2SECURITYLABEL 列の値が明示的に提供されていない
      • DB2SECURITYLABEL 列の値が明示的に提供されているが、セッション許可 ID がその値に対する書き込みアクセスを持たず、OVERRIDE NOT AUTHORIZED WRITE SECURITY LABEL オプションを使ってセキュリティー・ポリシーが生成されている
  • INSTEAD OF トリガー: MERGE ステートメントのターゲットとしてビューが指定される場合、 そのビューに対して、まったく INSTEAD OF トリガーを定義しないか、 更新、削除、挿入の各 INSTEAD OF トリガーを定義する必要があります (SQLSTATE 428FZ)。
  • 拡張標識変数の使用法: 使用可能な場合は、-1 から -7 までの範囲外にある負の標識変数値を入力にすることはできません (SQLSTATE 22010)。 また、デフォルトおよび未割り当ての拡張標識変数の値が使用可能な場合に、それらがサポートされないコンテキストで使用してはなりません (SQLSTATE 22539)。
  • assignment-clause の拡張標識変数: expression がソース表の単一の列、単一のホスト変数、または明示的にキャストされるホスト変数への参照である場合、拡張標識変数ベースの値が割り当てられる可能性があります。 未割り当ての拡張標識変数ベースの値を割り当てると、ステートメントで指定されなかったかのように、ターゲット列にその現行値がそのまま設定されることになります。 デフォルトの拡張標識変数ベースの値を割り当てると、列のデフォルト値が割り当てられます。 データ・タイプのデフォルト値については、 「CREATE TABLE」ステートメントのDEFAULT 節の説明を参照してください。

    ターゲット列が更新可能でない場合 (例えば、式として定義されているビュー内の列など)、未割り当ての拡張標識変数ベースの値を割り当てる必要があります (SQLSTATE 42808)。

    ターゲット列が GENERATED ALWAYS として定義されている場合、DEFAULT キーワード、またはデフォルトか未割り当ての拡張標識変数ベースの値を割り当てる必要があります (SQLSTATE 428C9)。

    assignment-clause では、未割り当ての拡張標識変数ベースの値にターゲット列のすべてを割り当ててはなりません (SQLSTATE 22540)。

  • insert-operation の拡張標識変数: expression がソース表の単一の列、単一のホスト変数、または明示的にキャストされるホスト変数への参照である場合、拡張標識変数ベースの値が挿入される可能性があります。 insert-operation で未割り当ての値を使用すると、列はそのデフォルト値に設定されます。

    ターゲット列が更新可能でない場合、それが GENERATED ALWAYS として定義されている列でなければ、未割り当ての拡張標識変数ベースの値を割り当てる必要があります (SQLSTATE 42808)。 ターゲット列が GENERATED ALWAYS として定義されている場合、DEFAULT キーワード、またはデフォルトか未割り当ての拡張標識変数ベースの値を割り当てる必要があります (SQLSTATE 428C9)。

MERGE ステートメントにおける更新、挿入、 または削除操作に関連した他の規則については、 該当するステートメントの『規則』セクションを参照してください。

  • 処理の順序:
    1. ソースからターゲットにかけて処理される行のセットを判別します。 このステートメントで CURRENT TIMESTAMP が使用される場合、 ステートメント全体でただ一度だけクロックが読み取られます。
    2. ON 節を使用して、 これらの行が MATCHED または NOT MATCHED のいずれであるかを分類します。
    3. WHEN 節内に matching-condition があれば評価します。
    4. assignment-clause および insert-operation 内に expression があれば評価します。
    5. それぞれの signal-statement を実行します。
    6. 指定された順序に従って、 それぞれの modification-operation を該当する行に適用します。 それぞれの modification-operation によってアクティブ化される制約およびトリガーが、 その modification-operation に関して実行されます。 ステートメント・レベルのトリガーは、 modification-operation を満たす行が存在しない場合でもアクティブ化されます。 それぞれの modification-operation は、 後続の各 modification-operation のトリガーや参照制約に影響する可能性があります。
  • ステートメント・レベルの原子性: MERGE ステートメントの実行中にエラーが発生した場合、 ステートメント全体がロールバックされます。
  • 更新される行数: MERGE ステートメントの実行が完了すると、 SQLCA の GET DIAGNOSTICS および SQLERRD(3) の ROW_COUNT 項目の値は、 MERGE ステートメントによって処理された行数になります (ELSE IGNORE 節によって識別された行を除く)。 SQLERRD(3) の値には、 制約またはトリガーの結果として処理された行数は含まれません。 SQLERRD(5) の値には、このような行の数が含まれます。
  • 挿入された行を更新することはできない: ターゲット内で、 MERGE ステートメントの実行前に存在しなかった行の更新操作は一切行われません。 つまり、MERGE ステートメントによって挿入された行は更新されません。
  • 拡張標識変数および更新トリガー: ターゲット列に未割り当ての拡張標識変数ベースの値が割り当てられている場合、その列は更新された列と見なされません。 その列は、ターゲット表で定義されるどの更新トリガーの OF column-name リストでも指定されなかったかのように扱われます。
  • 拡張標識変数および挿入トリガー: 拡張標識変数の使用によって、挿入トリガーのアクティブ化において変更が生じることはありません。 暗黙的または明示的な列リスト内のすべての列が未割り当てまたはデフォルトの拡張指標変数ベースの値に割り当てられた場合、すべての列にそれぞれのデフォルト値を持つ挿入が試行されます。 挿入に成功すると、挿入トリガーがアクティブ化されます。
  • 拡張標識変数および据え置きエラー・チェック: 更新不能列への挿入または更新を認識するための妥当性検査は、拡張標識変数が使用可能でない場合はステートメントの準備中に行われますが、拡張標識変数が使用可能な場合は、ステートメントの実行まで据え置かれます。 エラーを報告する必要があるかどうかは、実行時のみ判別できます。
  • システム期間テンポラル表に関する考慮事項: システム期間テンポラル表に対して MERGE が処理されるとき、特定のデータ変更操作が呼び出された場合と同様に、行に影響が及びます。 詳しくは、UPDATE ステートメント、DELETE ステートメント、および INSERT ステートメントのトピックを参照してください。
  • アプリケーション期間テンポラル表およびトリガーに関する考慮事項: ある行が削除されるときに、FOR PORTION OF BUSINESS_TIME 節が指定されている場合は、削除されなかった行の部分を表すために、追加の行が暗黙的に挿入される可能性があります。 削除される行に対して既存の削除トリガーがアクティブになり、暗黙的に挿入される行に対して既存の挿入トリガーがアクティブになります。 ある行が更新されるときに、FOR PORTION OF BUSINESS_TIME 節が指定されている場合は、更新されなかった行の部分を表すために、追加の行が暗黙的に挿入される可能性があります。 更新される行に対して既存の更新トリガーがアクティブになり、暗黙的に挿入される行に対して既存の挿入トリガーがアクティブになります。
  • insert-operation に列リストを使用しない MERGE の考慮事項: insert-operation の一部として列リストが指定されていない MERGE ステートメントには、暗黙的な非表示列は含まれません。 暗黙的に非表示として定義され、かつ NULL ではない列は、定義済みのデフォルト値を持つ必要があります。

  • 例 1: 記述 (description) が変更されたアクティビティーに関して、 アーカイブ表内の記述を更新します。 新しいアクティビティーについては、アーカイブ表に挿入します。 アーカイブ表とアクティビティー表にはどちらも、 主キーとしてアクティビティーが含まれます。
      MERGE INTO archive ar
      USING (SELECT activity, description FROM activities) ac
      ON (ar.activity = ac.activity)
      WHEN MATCHED THEN
         UPDATE SET
            description = ac.description
      WHEN NOT MATCHED THEN
         INSERT
            (activity, description)
            VALUES (ac.activity, ac.description)
  • 例 2: 出荷 (shipment) 表を使って、 在庫 (inventory) 表に行をマージします。その際、 出荷表のマッチした行の部品カウント (part count) ごとに数量を増分します。 そうでない場合は、新しい partno を在庫表に挿入します。
      MERGE INTO inventory AS in
      USING (SELECT partno, description, count FROM shipment
             WHERE shipment.partno IS NOT NULL) AS sh
      ON (in.partno = sh.partno)
      WHEN MATCHED THEN
         UPDATE SET
            description = sh.description,
            quantity = in.quantity + sh.count
      WHEN NOT MATCHED THEN
         INSERT
            (partno, description, quantity)
            VALUES (sh.partno, sh.description, sh.count)
  • 例 3:トランザクション (transaction) 表を使用して、アカウント (account) 表に行をマージします。その際、いくつかのトランザクション・セットのアカウント ID に対するバランスを更新し、 アカウントがまだ存在しない場合には、統合トランザクションからアカウントを新しく挿入します。
      MERGE INTO account AS a
      USING (SELECT id, sum(amount) sum_amount FROM transaction
             GROUP BY id) AS t
      ON a.id = t.id
      WHEN MATCHED THEN
         UPDATE SET
            balance = a.balance + t.sum_amount
      WHEN NOT MATCHED THEN
         INSERT
            (id, balance)
            VALUES (t.id, t.sum_amount)
  • 例 4: トランザクション・ログ (transaction_log) 表を使って、employee_file (従業員ファイル) 表に行をマージします。 その際、トランザクション時間に基づいて、最新のトランザクション・ログ (transaction_log) 行の内容で電話 (phone) および部署 (office) を更新します。最新の新しい従業員ファイル (employee_file) 行がまだ存在しない場合には、その行を挿入します。
      MERGE INTO employee_file AS e
      USING (SELECT empid, phone, office
             FROM (SELECT empid, phone, office,
                   ROW_NUMBER() OVER (PARTITION BY empid
                   ORDER BY transaction_time DESC) rn
                   FROM transaction_log) AS nt
                   WHERE rn = 1) AS t
      ON e.empid = t.empid
      WHEN MATCHED THEN
         UPDATE SET
            (phone, office) = 
            (t.phone, t.office)
      WHEN NOT MATCHED THEN
         INSERT
            (empid, phone, office)
            VALUES (t.empid, t.phone, t.office)
  • 例 5: 従業員 (employee) 行に動的に提供される値を使って、 既存の従業員に該当するデータの場合はマスター従業員 (employee) 表を更新します。 データが新しい従業員に関するものである場合は、行を挿入します。 次の例は、C プログラムのコードの断片です。
      hv1 =
      "MERGE INTO employee AS t
      USING TABLE(VALUES(CAST (? AS CHAR(6)), CAST (? AS VARCHAR(12)),
                         CAST (? AS CHAR(1)), CAST (? AS VARCHAR(15)),
                         CAST (? AS SMALLINT), CAST (? AS INTEGER)))
                         s(empno, firstnme, midinit, lastname, edlevel, salary)
      ON t.empno = s.empno
      WHEN MATCHED THEN
         UPDATE SET
            salary = s.salary
      WHEN NOT MATCHED THEN
         INSERT
            (empno, firstnme, midinit, lastname, edlevel, salary)
            VALUES (s.empno, s.firstnme, s.midinit, s.lastname, s.edlevel,
                    s.salary)";
      EXEC SQL PREPARE s1 FROM :hv1;
      EXEC SQL EXECUTE s1 USING '000420', 'SERGE', 'K', 'FIELDING', 18, 39580;
  • 例 6: Group A によって編成されたアクティビティーのリストをアーカイブ表内で更新します。 期限切れのアクティビティーをすべて削除し、 アーカイブ表のアクティビティー情報 (日付と記述) が変更されていれば、 それを更新します。 新規の着信アクティビティーについては、アーカイブ表に挿入します。 アクティビティーの日付が不明の場合、エラーを発します。 アーカイブ表内のアクティビティー日付の指定は必須です。 アクティビティー表は、それぞれのグループごとに存在します。 例えば、activities_groupA にはこのグループが編成したすべてのアクティビティーが含まれ、 アーカイブ表には企業のさまざまなグループによって編成された将来のアクティビティーがすべて含まれます。 アーカイブ表には主キーとして (group, activity) が存在し、日付は NULL 可能ではありません。 すべてのアクティビティー表には、 主キーとして activity が含まれます。 アーカイブ内の最終更新 (last_modified) 列は、 デフォルト値として CURRENT TIMESTAMP を使って定義されます。
      MERGE INTO archive ar
      USING (SELECT activity, description, date, last_modified
             FROM activities_groupA) ac
      ON (ar.activity = ac.activity) AND ar.group = 'A'
      WHEN MATCHED AND ac.date IS NULL THEN
         SIGNAL SQLSTATE '70001'
            SET MESSAGE_TEXT =
               ac.activity CONCAT ' cannot be modified. Reason: Date is not known'
      WHEN MATCHED AND ac.date < CURRENT DATE THEN
         DELETE
      WHEN MATCHED AND ar.last_modified < ac.last_modified THEN
         UPDATE SET
            (description, date, last_modified) = (ac.description, ac.date, DEFAULT)
      WHEN NOT MATCHED AND ac.date IS NULL THEN
         SIGNAL SQLSTATE '70002'
            SET MESSAGE_TEXT =
               ac.activity CONCAT ' cannot be inserted. Reason: Date is not known'
      WHEN NOT MATCHED AND ac.date >= CURRENT DATE THEN
         INSERT
            (group, activity, description, date) 
            VALUES ('A', ac.activity, ac.description, ac.date)
      ELSE IGNORE