アプリ版:「スタンプのみでお礼する」機能のリリースについて

顧客テーブルを更新テーブルのデータで更新したい。
No.顧客テーブル = No.更新テーブル です。

更新フィールドは、年齢、県 です。


●更新テーブル

No 年齢  県
--- ----- -------
1  30  埼玉
2  30  埼玉
3  30  埼玉

●顧客テーブル(現)

No 年齢  県
--- ----- -------
1  20  千葉
2  20  千葉
3  20  千葉
4  20  神奈川
5  20  福岡

●顧客テーブル(更新後)

No 年齢  県
--- ----- -------
1  30  埼玉
2  30  埼玉
3  30  埼玉
4  20  神奈川
5  20  福岡


この場合、1つのSQLで、複数レコードの複数フィールドを一括でUPDATEは出来ますでしょうか?

A 回答 (6件)

またまた実験してみました。


フィールド名を変えてみたり、型を変えてみたりしましたが、すぐに更新完了しました。

インデックスが原因で遅くなってないでしょうか?
インデックスは一意になっていますか?
(No.のみに一意制約がかかってますか?)

また、現在のテーブルをリネームしておいて、新たに同じ定義のテーブルを作成しなおし、リネームしたテーブルから入れてみてはどうでしょうか?
    • good
    • 0
この回答へのお礼

出来ました。

新テーブルにユニークキーを設置したら動きました。

テーブルを見直してみたところ、
主テーブル...Noがプライマリーキー
新テーブル...他コードがプライマリーキー、Noはキー設定なし。

となっていました。
キー設定のあるなしでこんなに動作に違いが出ると思いませんでした。

これでデータの更新は簡単に行えるのでひとまず安心しました。
本当にありがとうございました。

お礼日時:2005/02/08 16:51

下の回答した者です。


試しに、20000件のテーブルと500件のテーブルを用意して20000件のうち500件をアップデートしてみました。
SQLPlus WorkSheetで実行し、かかった時間は1分かかりませんでした。

ところで、SQLが帰ってこないというのはプログラムで実行しているのでしょうか?それともSQLWorkSheetなどでじかにSQL実行した結果でしょうか?
もしプログラムからしているのでしたら、プログラムのループ処理が無限ループに入っている可能性はないかチェックしてみてください。
また、直接SQLを実行していないならSQLWorkSheetなどでSQL単体で実行テストをしてみてください。

ちなみに当方の環境はOracle9iです

この回答への補足

いつもいろいろありがとうございます。

SQLは、SQL Plusで実行しています。
クライアントからとサーバから試しましたが同じ結果でした。

テストを実証していただいたので、同様にテストをしてみました。

テストテーブル1 + テストテーブル2
の更新だと問題なく動作します。しかもすごく高速で500件のデータ更新に数秒です。

これを
テストテーブル1 + 既存テーブル1
とすると25分。

既存テーブル1 + 既存テーブル2
SQLが終了しない。(2時間経過も終了しない)

となってしまいます。

テストテーブル1と2は全く同じ定義のフィールドを持つテーブル同士です。

フィールド名が異なる、フィールド長が異なる、フィールド定義が異なる、のが処理速度の遅さや停止の原因になってるのかとも思っています。

補足日時:2005/02/08 12:51
    • good
    • 0

>table_n が 500件、table_a が20000件ほどあります。


>よって更新するデータは500件ほどです。

ということは、Aの内容をBで更新するという事ですよね?
実際試されたSQLを見ると、本当は「更新される側」を更新する必要があるところを「更新する側」に更新をしていますね。
正しくは下のSQLでいけると思います。

UPDATE table_a a SET
(a.年齢,a.県)=(SELECT n.年齢,n.県 FROM table_n n WHERE n.CODE = a.CODE)
WHERE EXISTS (SELECT * FROM table_n n WHERE a.CODE = n.CODE)

この回答への補足

助言ありがとうございます。

更新用のテーブルで実行するとなぜか上手くいかず2時間以上たってもSQLが終了しません。

そこで仮のテーブルを作ってテストしたら400件のデータ更新で約20分ほどで更新されました。

いままで同じ処理をループをかけて1件づつ行っていました。このSQLも実行速度はあまり期待しないほうがよろしいのでしょうか? 

もうちょっと工夫してやってみます。

補足日時:2005/02/07 16:10
    • good
    • 1

質問にあるNo.というのはこれだけで一意になってるんですよね?


私の示したSQLではIDをNo.と置き換えて考えて頂けたでしょうか?
どんなSQLを書いて無理だったか貼り付けてもらえませんか?

SELECT COUNT(*) FROM TEST_M M
WHERE
EXISTS(SELECT * FROM TEST_S S WHERE S.ID = M.ID)

これで更新件数を確認できると思いますが、意図通りの更新件数が得られるでしょうか?

この回答への補足

Noは一意です。これがキーで、重複はありません。

UPDATE table_n n SET
(n.年齢,n.県)=(SELECT a.年齢,a.県 FROM table_a a WHERE a.CODE = p.CODE)
WHERE EXISTS (SELECT * FROM table_a a WHERE a.CODE = p.CODE)

CODEがIDと考えてください。

データは、
table_n が 500件、table_a が20000件ほどあります。
よって更新するデータは500件ほどです。

SQLを発行すると終了しなくなってしまいます。

オラクルのバージョンの問題でしょうか?
バージョンは、8.0.5とちょっと古いんです。

更新フィールドが1つのSQLは別のもので試したら動くのですが。

いままでデータを1件1件ループさせて更新していたのでSQL文をすっきりさせて処理の向上が図れればと思ってます。

よろしくお願いいたします。

補足日時:2005/02/04 17:28
    • good
    • 0

自分自身を更新の情報に参照することができなかったかと思います。

(別名を使っても)
ですのでまず、更新したい更新情報テーブルを作ってしまい、その情報を元に更新するしかないと思います・

参考までに・・
1.更新したいテーブル構造を作る
create table 更新情報テーブル AS select * from 更新元テーブル where ・・・
としてできたテーブル情報を手修正なり、一度trancateして変更情報をInsertなりして
更新情報テーブルを用意する。

>この場合、1つのSQLで、複数レコードの複数フィールドを一括でUPDATEは出来ますでしょうか?
更新元=更新先でUPDATEはできないと思うので、1つのSQLでは不可能だと・
2つのテーブルを用意したなら、後は連結させて更新するだけです。
    • good
    • 0

これでいけないでしょうか?


更新用をTEST_S、顧客テーブルをTEST_Mとします

UPDATE TEST_M M SET
(年齢,県)=(SELECT 年齢,県 FROM TEST_S S WHERE S.ID = M.ID)
WHERE
EXISTS(SELECT * FROM TEST_S S WHERE S.ID = M.ID)

この回答への補足

ヒントありがとうございます。

試してみたのですが、サーバが処理を終了してくれません。ループに入って終了しないような。

検索条件を絞って実行してみたのですが同じ結果です。
処理件数は500レコードほどです。
テストは7レコードでも行ってみました。

何が問題なんでしょうか?

補足日時:2005/02/04 14:18
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す


このQ&Aを見た人がよく見るQ&A