ストアドプロシージャ内での配列の使用方法と注意点

このQ&Aのポイント
  • アプリケーションから文字列の配列を引数として渡し、プロシージャ内でその配列の中身がなくなるまでループでUPDATE文を実行する方法について説明します。同じストアド内であれば、結果セットをカーソルに放り込みフェッチ&Whileで順番に取得することができますが、外部から引数として渡された配列をストアド内ループで順番に取得する方法についても解説します。また、配列数が多くなった時に遅くなりすぎる問題への対策についても考えてみましょう。
  • アプリケーション側で引数を特定してから渡す方法で配列個数分ストアドをコールする手段が取れますが、配列数が多くなると処理が遅くなる可能性があります。そのため、別のアプローチとして、引数として渡された配列を一度テーブルに格納してからループ処理を行う方法が考えられます。これにより処理速度の改善が期待できます。
  • ストアドプロシージャ内での配列の使用方法について、アプリケーション側とデータベース側の環境を考慮しながらループ処理の実装方法や処理速度の改善策について解説しました。また、外部から引数として渡された配列をストアド内ループで順番に取得する方法についても説明しました。配列数が多くなった場合のパフォーマンス問題には、一度テーブルに格納する方法が有効です。これらの方法を活用して、ストアドプロシージャ内での配列の使用をスムーズに行いましょう。
回答を見る
  • ベストアンサー

:ストアドプロシージャ内での配列の使用:

:ストアドプロシージャ内での配列の使用: 環境 アプリケーション側:C#.net データベース側:Oracle10g アプリケーションから文字列の配列を引数として渡し、 プロシージャ内でその配列の中身がなくなるまでループでUPDATE文を実行しようとしています。 引数例(文字列配列):para[] (para[0]='ねこ',para[1]='ねずみ',para[2]='たぬき',para[3]='人',…) While文1週目では「ねこ」を、2週目では「ねずみ」をSET句に格納したSQLを実行するのが目的です。 同じストアド内であれば、結果セットをカーソルに放り込み フェッチ&Whileで順番に取得する事ができますが、 外部から引数として渡された配列をストアド内ループで順番に取得するにはどうしたらよいのでしょうか? アプリ側で引数を特定してから渡せば配列個数文ストアドをコールするという手段が取れますが 配列数が多くなった時に遅くなりすぎるという問題があります。 どなたか詳しい方おりましたらご教授いただきたく思います。宜しくお願いします。

  • Oracle
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

C#でループしてupdate文発行すればストアドにする必要ないと思うけど。 ストアドでやるなら↓みたいな感じでどうでしょうか。 実行はしてないのでエラーになるかもしれません -- PL/SQL CREATE OR REPLACE PACKAGE TEST AS TYPE INREC_TYPE IS RECORD( HOGE VARCHAR2(2000) ,FOO VARCHAR2(2000) ); TYPE INTAB_TYPE IS TABLE OF INREC_TYPE INDEX BY BINARY_INTEGER; INTAB INTAB_TYPE; END TEST; / SHOW ERROR CREATE OR REPLACE PACKAGE BODY TEST AS PROCEDURE DOACTION AS BEGIN FOR idx IN INTAB.FIRST..INTAB.LAST LOOP -- update文 UPDATE TABLE SET HUGE = INTAB( idx ).HOGE WHERE HUGE = INTAB( idx ).FOO; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END DOACTION; END TEST; / SHOW ERROR -- sqlplus BEGIN -- パラメータ設定 TEST.INTAB(0).HOGE := "ほにゃらら"; TEST.INTAB(0).FOO := "ふにゃらら"; TEST.INTAB(1).HOGE := "ほにゃらら"; TEST.INTAB(1).FOO := "ふにゃらら"; -- 実行 TEST.DOACTION; END;

wendy0303
質問者

お礼

ありがとうございます。 お礼が遅くなりすいません。 いくつかの方法を模索し、紆余曲折ありましたが どうにか目的を果たすことができました。 5545233さんの回答は、直接使用する手法とはやや違うものになりましたが 私の理解の上で役に立つものでした。ありがとうございました。

関連するQ&A

  • SQL-Server 6.5でストアドプロシージャの実行

    EXECUTE procedure 'para1','para2' で正しい結果が返ってくるストプロがあります。 これをSELECT文の中で結果を返すようにするには どんな書き方をすれば良いのでしょうか? ストアドプロシージャを作成したのは今回が初めてで 試行錯誤しながらなんとか結果が返せるようになった のですが、私がISQLで試した方法ではうまく行きません。 <私の試した方法> SELECT procedure(tabe1.para1,tabe1.para2) FROM table1 SELECT文でストプロを実行することはできないのでしょうか? 宜しくお願いします。

  • MYSQLでストアドプロシージャの引数を二つ

    MYSQL初心者で参考書にかじりついてプログラミングしています。 主にDBの内容をPHPで吐き出させるといった使い方をしています。 SQL文があまりにも長ったらしくなってきたのでストアドプロシージャを使いたいのですが、使っているSQL文が (SELECT * FROM .変数. WHERE .変数. LIKE '.変数.') UNION (SELECT * FROM .変数. WHERE .変数. LIKE '.変数.'); となっており、引数を複数使えないとスッキリさせられない状況です。 ストアドプロシージャで複数の引数を設定することはできないのでしょうか?

    • ベストアンサー
    • MySQL
  • ストアドプロシージャの実行

    こんばんは。 C#のアプリケーションからストアドプロシージャの実行を検討 しています。ストアドプロシージャでは複数テーブルを更新する バッチシステムです。 このケースでは、C#側ではエラーをどこまでハンドリングするのが 良いでしょうか?。 「成功と失敗の戻り値だけ」か、それとも「ORA-」のようなエラーまで全てハンドリングすべきか迷っていまして・・。 ご意見お願いします。

  • ストアドプロシージャーの作成方法

    実行環境・・・CSE update文を5つ発行したくストアドプロシージャを使おうと思ったのですが上手くいかず 困っています。 create function 関数名 引数なし AS 'update文1,update文2,・・・・,update文5' language ='sql'; と行っているのですが、エラーが出てしまいます。 参考書に載っている引数ありのだと上手くいくのですが・・・ なにかやり方が間違っているのでしょうか? ご教授お願いいたします。

  • ストアドプロシージャについて

    お世話になります。 SQLServseのストアドプロシージャで、あるテーブルのテストデータを100件ほど作成したいと思っています。 しかし、プロシージャを実行すると「プライマリキーが重複しています」とエラーが出ます。 テーブル内にはすでにCODE='0001'と'0101'の2件が存在します。そのため挿入開始コードは'0002'としたのですが・・・。まだ同じエラーが発生します。 テーブル名:MST_USER  CODE char(4) ←キー  KBN  char(2)  NAME varchar(40)  PASS varchar(10) 作成したプロシージャ CREATE PROCEDURE dbo.test_update_USER AS declare @count int declare @kbn int set @count = 2 set @kbn = 0 while 1 = 1 begin update MST_USER set CODE = right('0000' + ltrim(str@count)), 4), KBN = right('00' + ltrim(str(@kbn)), 2), NAME = 'test' + ltrim(str(@count)), PASS = 'test' + ltrim(str(@count)) set @count = @count + 1 if (@count > 100) break if (@kbn > 3) set @kbn = 0 else set @kbn = @kbn + 1 end GO 何か間違えているのか自分ではわからなくなっている状態です。 どなたかご指摘いただけると幸いです。

  • ストアドプロシージャについて

    アドバイスを頂けたらと思います。 php   5.1.6 mysql   5.0.22 接続方法 PDO PHPよりストアドプロシージャを実行するとEXCUTEの部分で応答がなくなりMYSQLの SHOW PROCESSLIST を確認するとそのプロセスがSleep になってしまっています。 記述方法が間違っているか、またはどこか設定するのか、参考意見を 頂ければと思います。 PHP側 <?php try { $user = 'sys'; $pass = 'sys'; $dbh = new PDO('mysql:host=localhost;dbname=testDB', $user, $pass); if ($st = $dbh->prepare("CALL Listget()") ){ $st->execute(); while ($row = $st->fetch()) { print_r ($row); } } } catch (PDOException $e) { print 'Error: ' . $e->getMessage(). "\n"; } $dbh = null; ?> ストアド delimiter // CREATE PROCEDURE Listget ( ) BEGIN SELECT id FROM testTbl; END // よろしくお願いします。

    • ベストアンサー
    • PHP
  • ストアドプロシージャについて

    いつもお世話になっております。 ストアドプロシージャで以下のようなことをしたいのですが、可能しょうか。 ある会員テーブルから1件のレコード(10個のカラムで構成されている)を取得します。その10個のカラム⇒10個のレコードとして別の一時的なテーブルに格納したいのですが可能でしょうか。 イメージとしては、 (1)Select Clm1,Clm2,Clm3~,Clm10 from MstMember 条件句 (2)(1)の結果をtmpTBLに格納。中身としては、、、 <tmpTBL> Clm1 Clm2 Clm3 Clm10 とここまで書きましたが、やりたいことはSelect文で取得したレコードのカラム1~10を順番に参照したいだけです。 素人質問で大変恐縮ですがご教示頂けますと幸いです。

  • C#による.NETストアドプロシージャ

    VisualStudio+ODT.netで、C#にて「.NETストアドプロシージャ」を製作しようとしています。 例えばNUMBER型の値を引数で渡してNUMBER型値を返す様なFUNCTIONを作りたいとして、 Oracle側で使う際にNUMBER型の値にはNULL値も有り得るわけですが、 C#側でメソッドの引数や戻り値に、NULL許容型(int?やdecimal?とか)を指定してビルドし、 それをVisualStudioからOracleデータベースへデプロイしようとすると、 ウィザード上のパラメータマッピングのところで、NULL許容型に指定した引数や戻り値に対して Oracle側の適切なデータ型を指定出来なくなってしまいます。 かと言って、C#側メソッドでNULL許容型ではない型を指定してしまいますと、引数へNULL値を 与えると例外が発生してしまいます。 この様な問題に直面されて、何らか解決された方はいらっしゃいますでしょうか?

  • ストアドプロシージャのbegin、end

    下記の様なストアドプロシージャを作成し、VB側から実行させています。 どうしても、★SQL文2★の後のreturn文を実行してくれません。 (VB側ではreturn値が0と判断します。) このreturn文を★SQL文2★の前に移動すると、return値が-1として正常に取得できます。 begin、endのブロックの記述に何か間違いがあるのでしょうか? 環境:sqlserver2000,windows2000,vb6 よろしくお願いします。 CREATE PROCEDURE [sp_AAA] @PARAM1 varchar(16) AS begin if (~) begin ★SQL文1★ if (@@ERROR <> 0) begin return @@ERROR end end ★SQL文2★ return -1 ←ココ end

  • ストアドでのwhile文の利用法

    SQLServerでのストアドについてはこちらでうかがってもよろしいのでしょうか? ストアド内にてwhileでのループ文作成についてなんですが、 以下のようなストアドでSELECT内でA.NO1....とあるとおもうのですが、 これを@numRankの数だけ、A.NO(フィールド)を増やしたいのですが、 ここからどのようにつくればよろしいのでしょうか? CREATE PROCEDURE usp_Enquete @ask_idvarchar(10) AS DECLARE @strvarchar(1000) DECLARE @numRankint DECLARE @Counterint BEGIN SELECT @numRank = count(*) FROM B_Answer WHERE ask_id = @ask_id END SET NOCOUNT ON SET @Counter = 1 WHILE @Counter <= @numRank BEGIN SET @str = ' SELECT count(ansList.NO1) AS NumAns, A.NO1, A.NO2, A.NO3 FROM ・ ・ ・