Oracleで、1度のクエリで一括更新を行いたい

解決


yamada  2012-06-04 20:36:03  No: 42424

環境は
Delphi2010 Pro
Oracle 11gです。

Oracleへは、ADOで接続しています。

条件により、
複数回のUPDATEを行います。

SQL Serverで例にとると

var Query:TADOQuery;

Query.Add('UPDATE Tabele1 SET B = 10 WHERE A = 1;')
Query.Add('UPDATE Tabele1 SET B = 20 WHERE A = 2;')
Query.Add('UPDATE Tabele1 SET B = 30 WHERE A = 3;')
Query.Execute;

var sql:string;

sql:='UPDATE Tabele1 SET B = 10 WHERE A = 1;';
sql:=sql+'UPDATE Tabele1 SET B = 20 WHERE A = 2;';
sql:=sql+'UPDATE Tabele1 SET B = 30 WHERE A = 3;';
Query.Add(sql);
Query.Execute;

というような一括更新を行いたいのですが、
Oracleでの作り方がわかりません。

「/」で一文を区分けするようで、

Query.Add('UPDATE Tabele1 SET B = 10 WHERE A = 1');
Query.Add('/');
Query.Add('UPDATE Tabele1 SET B = 20 WHERE A = 2');
Query.Add('/');
Query.Add('UPDATE Tabele1 SET B = 30 WHERE A = 3');

とやってみましたが、やはりダメでした。

プロシージャの追加は事情によりできません。

ご教授いただけましたら、助かります。
宜しくお願いします。


初心者  2012-06-04 22:23:34  No: 42425

ダメだったとはどのようなエラーが表示されたのでしょうか?


yamada  2012-06-05 00:21:22  No: 42426

以下のエラーが表示されます。

---------------------------
デバッガ例外通知
---------------------------
プロジェクト Project1.exe は例外クラス EOleException (メッセージ 'ORA-00936: 式がありません。')を送出しました。
---------------------------
ブレーク(B)   継続(C)   ヘルプ   
---------------------------


初心者  2012-06-05 00:58:03  No: 42427

TQueryのコンポーネントを使って
SQLの中に
UPDATE Tabele1 SET B = 10 WHERE A = 1
/
UPDATE Tabele1 SET B = 20 WHERE A = 2
/
UPDATE Tabele1 SET B = 30 WHERE A = 3
を入れて実行してもエラーは表示されますか?


yamada  2012-06-05 01:12:29  No: 42428

残念ながら、同様の結果でした。


初心者  2012-06-05 01:18:41  No: 42429

UPDATE Tabele1 
SET B = decode(A,1,10,2,20,3,30) 
WHERE A in (1,2,3)
ではどうでしょう?


yamda  2012-06-05 01:44:20  No: 42430

ご教授ありがとうございます。

1万件以上の更新件数でして、
DECODEのパラメータ数の上限は 255らしく、、
今回は使えません。。。。


初心者  2012-06-05 01:58:02  No: 42431

となると実際のSQLを見ないとわからないですね、
エラー内容はSQL文が間違っているとしか言えない状況なので・・・


yamada  2012-06-05 02:09:13  No: 42432

そうですかぁ。

UPDATE Tabele1 SET B = 10 WHERE A = 1
の1行だけなら、問題ないのですが、続けて発行したいとなると
難しいのですかね。

1点伝え忘れたことがありました。
「/」は、ObjectBrowserというツール上の話でして、
Delphiからも、同様のことができるかな、と思い質問させていただきました。


初心者  2012-06-05 02:14:28  No: 42433

SQLはループ処理でaddしてると思うのですが、ループが終了した段階で
SQLの内容をtextで出力して、ObjectBrowserで動かしてみてはどうでしょうか?
動かないのならどこかでSQLが間違っている可能性があります


yamada  2012-06-05 02:30:57  No: 42434

先ほどの書込みで、
TQueryのコンポーネントを使って
SQLプロパティの中に文を入れて実行して、エラーが出力されてましたが、

同様の文をObjectBrowserにコピー貼り付けして実行すると、
問題なく、2回応答が返ってきます。

UPDATE文自体は、
UPDATE SyohinMst SET Zaiko = 10 WHERE SyohinNo = 1
というシンプルなものです。


nobukoshi802  2012-06-05 05:47:33  No: 42435

ストアドプロシージャはNGですが
無記名ストアドプロシージャはダメでしょうか?

declare
 vCount NUMBER(4) := 0;
begin
UPDATE Tabele1 SET B = 10 WHERE A = 1;
UPDATE Tabele1 SET B = 20 WHERE A = 2;
UPDATE Tabele1 SET B = 30 WHERE A = 3;
end;


yamada  2012-06-05 18:08:30  No: 42436

nobukoshi802さんありがとうございます。

知識不足ですいませんが、
無記名ストアドプロシージャとは何でしょう?
検索しましたが、それらしきものはなく、
どのようなものか教えて下さい。

よろしくお願いします。


初心者  2012-06-05 19:17:35  No: 42437

DECODEが無理ならcase文ならいけるのでは?と思いました。


nobukoshi802  2012-06-05 20:39:14  No: 42438

書き方が悪かったですね、無記名ストアドプロシージャ
では無く、無名ストアドプロシージャが一般的でした。

多分、ストアドが利用出来ないのは、Oracleのストアドが読め無い
もしくは、管理したくない場合と思われます。

SQL Plusで、Create Stored〜の部分無しで
declareから始まるSQLを発行して見てください。
それで、ストアドスロシージャが実行されます。

これでOracleのストアド知識も向上するので、がんばってください。


yamada  2012-06-08 02:56:55  No: 42439

nobukoshi802さんありがとうございます。

ストアドプロシージャに関しては、
あまりまだ作ったことがないので、
登録したくないな、というのはありました。

無名ストアドプロシージャに関しては、
調べまして、登録なしで使えるということはわかりました。

SQL Plus上で実行させてみて、実際に使えましたが、
どうDelphiで反映させればよいのかがわかりません。

TADOStoredProcコンポーネントは、
登録されているプロシージャの実行が、
基本であるという認識なのですが。

あらかじめ、スクリプトファイルを作成しなくても
リアルタイムでDelphi上から実行させたいのですが、
方法をご存知でしたら教えてください。
宜しくお願いします。


nobukoshi802  2012-06-08 05:14:45  No: 42440

yamadaさんが、SQL Plusで実行したSQLをTADOQueryで実行してください。
変数が必要な場合は、declareから開始します。
変数が不要なら、beginから開始します。


yamada  2012-06-19 00:07:08  No: 42441

初心者さん、
nobukoshi802さん、
ありがとうございました。

上記のnobukoshi802さんの方法解決いたしました。
質問内容的には、わからずじまいですが、
代替の方が応用効きそうなので、
こちらの方を使わせて頂きます。

色々と勉強になりました。

お二方に感謝です。
ありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加