2017/12/07
1回のSQLでデータ登録と更新を実現する便利なSQL文のMERGE文ですが、少し変わった使い方を本記事では紹介します。
oracle10gから出来るようになった使い方で、それ以降のバージョンで使用する事が出来ます。
sponsored link
存在する場合の更新のみ実施
MERGE文は、DML文の1つで、元テーブルのデータが先のテーブルに存在すれば更新、存在しなければ登録を1度に行うSQLですが、更新のみや登録のみを行うことが出来ます。
更新のみ行いたい場合は、WHEN MATCHEDのみを記述し、WHEN NOT MATCHEDを記述しないことで実現する事が出来ます。
他のテーブルの値でデータ更新する場合に、最適な実行計画で実現出来る方法の一つです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
-- 実行前 -- test_table1 A B C D --- ----- --- --- 001 00001 003 00003 -- test_table2 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN MATCHED THEN UPDATE SET c = t2.c ,d = t2.d ; -- 実行後 -- test_table1 A B C D --- ----- --- --- 001 00001 100 999 ← このデータが更新された 003 00003 |
存在しない場合の登録のみ実施
登録のみ行いたい場合は、WHEN NOT MATCHEDのみを記述し、WHEN MATCHEDを記述しないことで実現する事が出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
-- 実行前 -- test_table1 A B C D --- ----- --- --- 001 00001 003 00003 -- test_table2 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN NOT MATCHED THEN INSERT (a,b,c,d) VALUES (t2.a,t2.b,t2.c,t2.d) ; -- 実行後 -- test_table1 A B C D --- ----- --- --- 001 00001 002 00002 200 888 ← このデータが登録された 003 00003 |
更新や登録時に条件を指定する
更新や登録時に、条件を指定し特定のデータのみ更新や登録を行うことが出来ます。
UPDATEやINSERTの後ろにWHERE句を指定することで実現できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
-- 実行前 -- test_table1 A B C D --- ----- --- --- 003 00003 004 00004 -- test_table2 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 003 00003 300 777 004 00004 400 666 MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN MATCHED THEN UPDATE SET c = t2.c ,d = t2.d WHERE t2.d = 777 WHEN NOT MATCHED THEN INSERT (a,b,c,d) VALUES (t2.a,t2.b,t2.c,t2.d) WHERE t2.d = 999 ; -- 実行後 -- test_table1 A B C D --- ----- --- --- 001 00001 100 999 ← このデータが登録された 003 00003 300 777 ← このデータが更新された 004 00004 |
更新後、データを削除する
MERGE文のWHEN MATCHEDでデータを更新後、条件を指定しデータを削除する事も可能です。
例えば、論理削除されているデータは、更新先テーブルから削除するという使い方が考えられます。
WHEN MATCHEDのUPDATEの後に、DELETE WHERE 条件 を記述します。更新後のデータの値で条件を評価します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
-- 実行前 -- test_table1 A B C D --- ----- --- --- 001 00001 002 00002 003 00003 -- test_table2 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 003 00003 300 777 MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN MATCHED THEN UPDATE SET c = t2.c ,d = t2.d DELETE WHERE c = 300 ; -- 実行後 -- test_table1 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 (更新後の項目cの値が300のデータが削除された) |
注意点として、更新したデータのみ削除が有効ということです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
-- 実行前 -- test_table1 A B C D --- ----- --- --- 001 00001 300 002 00002 200 003 00003 300 -- test_table2 A B C D --- ----- --- --- 001 00001 100 999 002 00002 200 888 003 00003 300 777 MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN MATCHED THEN UPDATE SET c = t2.c ,d = t2.d WHERE t2.d IN(888,777) DELETE WHERE c = 300 ; -- 実行後 -- test_table1 A B C D --- ----- --- --- 001 00001 300 ← 更新されていないデータなので削除されない 002 00002 200 888 |
まとめ
MERGE文について、少し変わった使い方を見てきました。
様々な使い方を把握することで、1回のMERGE文で実現出来ることが増えます。また、全体の処理時間を短縮出来る可能性もあります。
MERGE文は様々なことが出来るので理解が大変です。少しずつ理解していきましょう。
関連