2017/12/07
ORACLEのMERGE文、1回のSQLでデータ登録と更新を実現する便利なSQL文ですが、気をつけないと実行エラーとなることがあります。
本記事では、MERGE文のエラーになるケース3つを紹介します。
sponsored link
ON句で指定した項目については、更新が出来ない
ON句で指定した項目については、更新が出来ません。
ON句で指定した項目を更新しようとすると、エラー(ORA-38104)が発生します。
1 2 3 4 5 6 7 8 9 10 11 12 |
MERGE INTO test_table1 t1 USING test_table2 t2 ON( t1.a = t2.a AND t1.b = t2.b ) WHEN MATCHED THEN UPDATE SET b = t2.e ,c = t2.c ,d = t2.d ; ORA-38104: ON句で参照する列は更新できません: "T1"."B" |
マージ元テーブルに同一キーのデータが複数(データ登録時)
マージ先テーブルに同一キーのデータが存在しない場合、MERGE文ではデータ登録を行います。
その場合でマージ元テーブルに同一キーのデータが複数存在した場合で、かつ、マージ先テーブルに主キーや一意キーが設定されている場合、キー重複エラー(ORA-00001)が発生します。
1件目でデータ登録、2件目でデータを更新というような動作はしません。(そもそもどちらを最終値とするか、という問題になるため、エラーとして落とした方が分かりやすいので、よい動作かと個人的には思います)
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 |
-- test_table1(項目A+項目Bが主キー) A B C D --- ----- --- --- 001 00001 -- test_table2 A B C D --- ----- --- --- 002 00002 200 888 002 00002 300 777 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) ; ORA-00001: 一意制約(zzzzz.yyyyy)に反しています zzzzz:スキーマ名 yyyyy:主キー名・一意キー名 |
マージ元テーブルに同一キーのデータが複数(データ更新時)
マージ先テーブルに同一キーのデータが存在する場合、MERGE文ではデータ更新を行います。
その場合でマージ元テーブルに同一キーのデータが複数存在した場合、エラー(ORA-30926)が発生します。
それぞれのデータで、2回更新というような動作はしません。(これについても、そもそもどちらを最終値とするか、という問題になるため、エラーとして落とした方が分かりやすいので、よい動作かと個人的には思います)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
-- test_table1(項目A+項目Bが主キー) A B C D --- ----- --- --- 002 00002 -- test_table2 A B C D --- ----- --- --- 002 00002 200 888 002 00002 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 ; ORA-30926: ソース表の安定したセット行を取得できません |
ただし、私の環境だとマージ元とマージ先で全て同一データであった場合、エラーとならない現象が起こりました。
マージ元テーブルに同一キーのデータが複数あっただけで、エラーになるというわけではなさそうなので注意が必要です。(テストでは問題なかったけど、本番で異常終了するなど)
まとめ
MERGE文について、気をつけるべき3つのエラーケースを見てきました。
特にマージ元テーブルに同一キーのデータが複数というのは、「テスト時にはそういったデータが発生することを想定していなかったので問題にならず、本番で障害が発生した」ということが起こりえます。
便利なMERGE文ですが、使う際には注意が必要です。
関連