連載
» 2012年12月03日 17時55分 公開

Webブラウザで気軽に学ぶ実践SQL講座(14):SQLでデータを操作する(副問合せを利用したINSERT/相関UPDATE/MERGE) (2/3)

[須々木尚子(すすき なおこ),日本オラクル]

MERGE文:条件によって挿入または更新する

 最後に、少し特殊なデータ更新の構文を紹介します。2つの表を比較して、一致する行が存在しなければINSERT、一致する行が存在すればUPDATEする、「MERGE」という構文です。

 MERGE文を試すために、新たに「MY_PROD」(商品表)と「MY_PROD_UPDATE」(商品改定表)という新しい表を作成しましょう。「MY_PROD」は商品マスターです。一方、「MY_PROD_UPDATE」には、新しく追加する商品や、価格更新する商品の情報が記録されています。定期的に商品の種類や価格を更新するため、「MY_PROD_UPDATE」に新しく追加する商品や、価格更新する商品の情報を入力し、MY_PRODに反映させることをイメージしてください。それでは実際に、以下のSQL文をコピーして、表を作成し、初期データを挿入しましょう。

CREATE TABLE my_prod
(prod_id   number(3),
 prod_name varchar2(25),
 price     number(6)
);
CREATE TABLE my_prod_update
(prod_id   number(3),
 prod_name varchar2(25),
 price     number(6)
);
INSERT INTO my_prod VALUES(1,'えんぴつ',50);
INSERT INTO my_prod VALUES(2,'消しゴム',100);
INSERT INTO my_prod VALUES(3,'下敷き',200);
INSERT INTO my_prod_update VALUES(1,'えんぴつ',70);
INSERT INTO my_prod_update VALUES(4,'シャープペンシル',150);

 間違えてしまった場合や、やり直したい場合には、次のSQL文を使って一度表を削除し、作成し直してください。

DROP TABLE my_prod;
DROP TABLE my_prod_update;

 検索すると、以下のような「MY_PROD」表と、「MY_PROD_UPDATE」表が作成されたことが分かります。

SELECT * FROM my_prod;
図6 「MY_PROD」表
SELECT * FROM my_prod_update;
図7 「MY_PROD_UPDATE」

「一致するデータがあれば更新、そうでなければ挿入」はどう書く?

 それでは、MERGE文を使って、「MY_PROD」表に、「MY_PROD_UPDATE」のデータを反映させましょう。MERGE文では、2つの表を比較し、一致するデータがある場合は更新(今回の例では、すでにMY_PROD表に登録されている商品であれば、価格の改定)を、一致するデータがない場合には挿入(MY_PROD表に登録されていない新規商品であれば新たに追加)を行います。このように「一致するデータがある場合には更新」「一致しないデータがある場合は挿入」という処理を、MERGE文では以下のような構文で記述します。

MERGE文の構文

MERGE INTO  更新する表
      USING 参照する表
ON    (更新する表と参照する表を結合する条件)
WHEN  MATCHED THEN 
   UPDATE・・・
WHEN  NOT MATCHED THEN 
   INSERT・・・

 それでは実行してみましょう。UPDATE句とINSERT句の書き方が今までと少し異なるので注意してください。下記のように指定すると、「my_prod_update(uという別名を指定)を使って、my_prod(pという別名を指定)表に対してマージ操作を行う。一致するデータがあれば(商品が既に登録されていれば)、my_prod(p)のprice列に、my_prod_update(u)の改定後価格を更新する。一致するデータがなければ(まだ商品が登録されていなければ)、my_prod(p)の各列にmy_prod_update(u)の値を新規挿入する」という意味になります。

MERGE INTO  my_prod p
      USING my_prod_update u
ON    (p.prod_id=u.prod_id)
WHEN  MATCHED THEN 
   UPDATE SET p.price=u.price
WHEN  NOT MATCHED THEN 
   INSERT (p.prod_id,p.prod_name,p.price)
      VALUES (u.prod_id,u.prod_name,u.price);
図8 MERGE文で条件を指定してデータを挿入する

 それでは、MY_PROD表のデータを確認してみましょう。

SELECT * FROM my_prod;
図9 図8で指定した通りの内容になっている

 結果を確認すると、「えんぴつ」の値段が更新され、さらに新たに「シャープペンシル」が追加されていることが分かります。

 今回のように、既存の表データを基にINSERTやUPDATEを行いたい場合には、MERGE文を使うと便利です。単に1つの構文で実行できるだけでなく、データベース内でも1回の処理で行われるため、パフォーマンス面でもメリットがあります。ぜひ使ってみてください。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。