- ベストアンサー
updateの一括実行
SQLに関しまして質問させて頂きます。 更新元テーブルA、マスタテーブルB、更新先テーブルCがあり、 以下のような条件を一つのSQL文で実現したいと思っています。 【条件】 (1)Aのe列が1のものを対象に更新をかける (2)条件(1)を満たすレコードの各所属&氏名をマスタBのIDに置き換え、テーブルCに更新 【テーブルA(更新元)】 ----------------------------------------------- No 所属1 氏名1 所属2 氏名2 所属3 氏名3 e 01 A01 ああ A01 いい C01 おお 1 02 A01 いい A01 うう C01 おお 0 03 B01 ああ B01 ええ C01 おお 1 ----------------------------------------------- 【テーブルB(マスタ)】 ----------------- ID 所属 氏名 001 A01 ああ 002 A01 いい 003 B01 ああ : ----------------- 【テーブルC(更新先)】 ------------------ No ID1 ID2 ID3 01 001 002 025 02 002 003 025 03 011 014 025 ------------------ テーブルAが1レコードであれば update C set ID1=(select ID from A, B where A.所属1=B.所属 AND A.氏名1=B.氏名) ID2=(select ID from A, B where A.所属2=B.所属 AND A.氏名2=B.氏名) ID3=(select ID from A, B where A.所属3=B.所属 AND A.氏名3=B.氏名) where No='01' で行くのですが、10000行の更新で10000回update文を発行すると処理に時間がかかります。 そこで、updateの一括実行を行いたいと考えています。 ご存知の方がいらしましたら、 ご教授よろしくお願い致しますm(_ _)m 【環境】 oracle 9i
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
何を悩んでいるのか理解するのに時間がかかりました..(^^ あなたが書かれたUPDATE文で使っているサブクエリは、 更新対象のCとAやBの条件を書いていないので、 予め対象を限定しないと誤動作するのです。 原則として、UPDATEで使うサブクエリは、相関サブクエリに なるように、更新対象テーブルとの関係をサブクエリの条件に 加える必要があると認識してください。 例えば、こんな感じ。 update C set ID1=(select ID from A, B where C.No=A.No AND A.e=1 AND A.所属1=B.所属 AND A.氏名1=B.氏名), ID2=(select ID from A, B where C.No=A.No AND A.e=1 AND A.所属2=B.所属 AND A.氏名2=B.氏名), ID3=(select ID from A, B where C.No=A.No AND A.e=1 AND A.所属3=B.所属 AND A.氏名3=B.氏名), where exists(select 1 from A where A.e=1 and A.No=C.No) ;
その他の回答 (2)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>所属と氏名が入っていない場合(所属B,氏名Bがなしの場合。どちらかが無いのは無い)もあるのですが、selectでマスタ値のみとってくるとそのあたりはどうなりますか?nullでしょうか?それともその列が返ってこない? #1で書いたSQLでは返ってきません。 理由は、Aテーブルと各Bテーブルの結合が内部結合だからです。 外部結合にすれば、IDはnullで返されます。
補足
上記どおり、外部結合にして試してみましたが、30分ほど待ってみても結果が返ってきませんでした。。。 件数が多すぎるのが問題でしょうか。。。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
update C set(ID1, ID2, ID3) = ( select B1.ID, B2.ID, B3.ID form A, B B1, B B2, B B3 where A.所属1=B1.所属 AND A.氏名1=B1.氏名 and A.所属2=B2.所属 AND A.氏名2=B2.氏名 and A.所属3=B3.所属 AND A.氏名3=B3.氏名 and A.e = 1 and A.No = C.No) こんな感じかな? setの書き方はOracleの方言ですので他のDBでは使えません。 #テーブルAがIDじゃなく所属と名前を持っている構成がよくわかりませんが・・・
補足
早速のご回答ありがとうございます。 所属と氏名が入っていない場合(所属B,氏名Bがなしの場合。どちらかが無いのは無い)もあるのですが、selectでマスタ値のみとってくるとそのあたりはどうなりますか?nullでしょうか?それともその列が返ってこない? 情報が不十分ですみません。 #テーブルAがIDじゃなく所属と名前を持っている構成がよくわかりませんが・・・ ファイルをそのままワーク表として読み込んだので、こうなりました。。。
お礼
回答ありがとうございます。この方法で100件の更新が成功したので10000件の更新ができるよう頑張ります。 初め上記方法に似たSQLでやっていたのですが、サブクエリの方で複数行返ってきてしまい実行できませんでした。その理由が「原則として・・・」ですべてが理解できました。 この度は本当にありがとうございます。今後ともよろしくお願いします。