Oracle の UPSERT (MERGE)

MySQLPostgreSQL についての UPSERT 文はこれまでに以下を書いてきたが、
Oracle の UPSERT (MERGE)を書いてなかったので、書き方を書いておくことにした。

MySQL で UPSERT する時に考えること - Oboe吹きプログラマの黙示録

PostgreSQL のアップサートとMySQLのアップサート - Oboe吹きプログラマの黙示録

PostgreSQL conflict upsert のトリック - Oboe吹きプログラマの黙示録

JSONB の primary key を作る ( by PosetgreSQL ) - Oboe吹きプログラマの黙示録

JSONB のキーと他のキーの複合キー(by PostgreSQL) - Oboe吹きプログラマの黙示録

Oracle の UPSERT (MERGE) は、2つのテーブルをマージする文のSQLで記述することであり、
この点が他のDBと違和感がある。

2つのテーブルのマージとしての書き方
table_a テーブルに、挿入目的の table_b テーブルのレコードを、更新or挿入するマージ文
(table_a テーブルとtable_b テーブルのカラム構造が同じである時)

MERGE INTO table_a a USING table_b b ON (a.id = b.id, a.sub_cd = b.sub_cd)
WHEN MATCHED THEN
  UPDATE SET
  a.col_1 = b.col_2 ,
  a.col_2 = b.col_2
WHEN NOT MATCHED THEN
  INSERT INTO (id, sub_cd, col_1, col_2)
  VALUES (b. id, b.sub_cd, b.col_1, b.col_2)

1テーブルにレコードのマージとしての書き方
dual を利用する

MERGE INTO table_a a USING (
  SELECT 11      AS id, 
         101     AS sub_cd,
         'A'     AS col_1,
        2031     AS col_2
  FROM dual
) b
 ON (a.id = b.id, a.sub_cd = b.sub_cd)
WHEN MATCHED THEN
  UPDATE SET
  a.col_1 = b.col_2 ,
  a.col_2 = b.col_2
WHEN NOT MATCHED THEN
  INSERT INTO (id, sub_cd, col_1, col_2)
  VALUES (b. id, b.sub_cd, b.col_1, b.col_2)