• ベストアンサー

stored procedureの引数について

stored procedureに可変長引数(配列)等を渡す方法またはその代替案を教えていただけないでしょうか? マニュアルを見る限りではないようです。 text型(varcharはmaxを超えてしまう)にカンマ区切りで値を結合してprocedureのほうで分割するような処理をしないとだめなのでしょうか?

noname#18328
noname#18328

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

  • ベストアンサー
  • jamra
  • ベストアンサー率43% (10/23)
回答No.1

その1  プログラム上で、テンポラリテーブルを作成し、  データを書き出す。  その後、ストアドプロシージャを呼び出し、  ストアドプロシージャ内で、テンポラリテーブルより  データを取得する。  ※プログラム側で、トランザクションを制御する。 ◎その2  プログラムで、CSVファイルとして吐き出す。  ストアドプロシージャを呼び出し、ストアドプロシージャ内で、  BULK INSERTで取得する。  ※WEBアプリなどなら、セッション変数+時間で、   CSVファイル名を一意にする。

noname#18328
質問者

お礼

やはり、上記のような方法をするしかないのですね。 大変参考になりました。ありがとうございます。

関連するQ&A

  • ストアドプロシージャでN個の引数を与える方法

    SQL Server 2012 の環境でカンマ区切りでN個の要素を引数としてストアドプロシージャを実行したいのですが、可能でしょうか?(CONCAT関数のような指定方法をイメージしています。) 【呼出イメージ】 EXECUTE StoredTest N'10001', N'10002', N'10003', N'10004' ...N すみませんが、どなたかご教示いただけないでしょうか?

  • ストアドプロシージャ作成時のエラーについて

    お世話になっております。 CREATE PROCEDURE AAA (IN param INT) BEGIN SELECT CD, NAME FROM TBL WHERE TBL_KEY = param; END INTEGER型の引数を渡してVARCHAR型のCD、NAMEを取り出す程度のストアドプロシージャを作成しようとすると 1303 - Can't create a PROCEDURE from within another stored routine. なるエラーが表示されて作成ができません。 このエラーの理由についてコメント頂ければ幸いです。

    • ベストアンサー
    • MySQL
  • マルチレイアウト

    1テーブルでレコード毎にレコード長の違うテキスト(CSV)ファイルを出力したいのですが、通常VBソースを生成するツールを使っていて、シングルレイアウトしか対応していません。 しかも、可変長の""引用符くくり(TEXT項目)のカンマ区切りしか出力できません。 実際に欲しいのは、可変長の""くくりなし(TEXT項目)のカンマ区切りです。 内容は例えば項目数10のレコード(A)、項目数5のレコード(B)、(A)、(B)・・・の繰り返しです。 よろしくお願いします。

  • ストアドファンクション⇒プロシージャ呼出し失敗する

    参考の通りに、ストアドプロシージャ作成SQL文を発行し、 コマンドライン上からは、以下の通りの結果1となり、 レコードがinsertされます。 <結果1> mysql> call logger('ほげ', 'ホゲ'); Query OK, 1 row affected (0.01 sec) mysql> select * from PROCEDURE_LOG; +--------+--------+---------------------+ | NAME | QUERY | EXECUTE_DATE | +--------+--------+---------------------+ | ほげ | ホゲ | 2014-03-26 10:41:26 | +--------+--------+---------------------+ 1 row in set (0.00 sec) ですが、testというストアドファンクションから呼び出してみましたが、 以下の結果2の通り、失敗します。 <結果2> mysql> select test(); ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger <test> BEGIN CALL logger('test','1'); RETURN CONCAT('END'); END 現在動作している環境では、どこでエラーが発生したかがわからず、 ロガーの処理をなんとしても実装したいのですが、 いろいろ試してみても、解決できませんでした。 ご教示のほど、よろしくお願いします。 <参考> http://treeapps.hatenablog.com/entry/20120106/p1 <ストアドプロシージャ作成SQL文(logger)> SET NAMES UTF8; delimiter // -- ログ出力 DROP PROCEDURE IF EXISTS logger// CREATE PROCEDURE logger( IN PROCEDURE_NAME TEXT, IN SQL_TEXT TEXT ) BEGIN DECLARE CNT INT; CREATE TABLE IF NOT EXISTS PROCEDURE_LOG ( NAME VARCHAR(64), QUERY TEXT, EXECUTE_DATE TIMESTAMP, KEY IDX1 (NAME, QUERY(64), EXECUTE_DATE) ) ENGINE=MYISAM DEFAULT CHARSET=UTF8; -- 古いログを削除 SELECT COUNT(*) INTO CNT FROM PROCEDURE_LOG; IF CNT >= 1000 THEN DELETE FROM PROCEDURE_LOG LIMIT 1; END IF; -- テーブルにログを記録 SET @sql = CONCAT('INSERT INTO PROCEDURE_LOG VALUES (', QUOTE(PROCEDURE_NAME), ',', QUOTE(SQL_TEXT), ', null)'); PREPARE stmt FROM @sql; EXECUTE stmt; END // delimiter ;

    • ベストアンサー
    • MySQL
  • 引数の渡し方

    いつもお世話になっています。 外部テキスト(data.txt)を読み込んで、内容を配列(txtN)に格納、 表示するスクリプトを組んでいます。 myNameは複数あり、ボタンから渡される引数に応じて myNameを切り替えてtrace(実際には表示)させたいんですが、方法が分かりません。 以下フレームアクション //Shift-JISで読み込む System.useCodepage = true; load_obj = new LoadVars(); load_obj.load( "data.txt" ); load_obj.onLoad = function( success ){ //正常終了時、カンマで分割して配列に格納 if( success ){ my_ary = new Array(); my_ary = load_obj.myName.split(","); } txt01=my_ary[0]; txt02=my_ary[1]; txt03=my_ary[2]; txt04=my_ary[3]; trace(txt01); trace(txt02); trace(txt03); trace(txt04); }; stop(); よろしくお願いします。

    • ベストアンサー
    • Flash
  • PLSQLでのSQLの実行に関しての質問

    [環境] db:oracle 11g express edition os:windowsXP 言語:PLSQL [質問] PLSQLを使用したプログラムを作成していたのですが、SQLの文字数がVARCHAR2(32767)で宣言した変数の文字数を超えてしまいエラーとなります。 理由としては、引数で受け取った配列の数分だけUNIONでSQLを結合し、変数に格納しているのですが、配列の量が多いと変数の最大文字列を超えてしまうようです。(ソースイメージは下記に記述) 対応としては、変数を分割し、SQLを実行することや、SQLを組みなおすなどの対応が考えられるのですが、”(1)処理速度の都合上、できれば1度のSQLで実行したい。”、”(2)抽出条件が配列の条件によって、複雑に変わることと、既に稼働しているプログラムの為あまりソースを変更したくない”という理由から検索条件は変えずに、1度のSQLでどうにか実行できないかと考えています。 上記条件をクリアする何か良い方法はありますでしょうか? (もし、1回のSQLで実行は難しいのであれば、最悪配列を使用してSQLを分割して対応しようとは思っています。ただ、他に方法があるのであればそれに越したことはないです。) どなたか良い方法をご存知の方がおりましたら教えていただけないでしょうか? 宜しくお願い致します。 [ソースイメージ] <引数> 配列[100];          <-- 条件が格納された配列 <変数定義部> hensu_union VARCHAR2(32767); <-- 結合したSQLを格納 hensu_where VARCHAR2(1000); <-- SELECTの条件の格納 <プログラム部>  <省略>  .  .  .   FOR i IN 1..配列分 LOOP <-- 配列の数分、UNIONでSQLを結合 IF i > 1 THEN hensu_union := hensu_union || 'union '; END IF; hensu_union := hensu_union || 'select A,B,C .... from マスタA、マスタB WHERE ' || hensu_where ;  ←ここのUNIONで結合しすぎると最大文字列を超えエラー  END LOOP; . .  省略 . .   OPEN カーソル名 FOR hensu_union ; ←SQLを実行する部分でどうにか1回で済ませたい。                    VARCHAR2を超えるような文字列を格納できたり、                    他の良い方法はあるのか?

  • c# 配列の受け取り方

    こんにちは、 c#言語で、RETURNの返しが配列の場合 どのように疎ければよいのでしょうか? メイン処理 strmtcにrun_mainから帰ってくる配列を格納したい string[] strmtc = run_main(""); run_main処理 // カンマ区切りで分割して配列に格納する string[] sarray; sarray = s.Split(','); return sarray;

  • C#でcsvファイルの列を入れ替えたい

    C#初心者です。 以下のように、カンマ区切りのcsvファイルの特定の列を入れ替えて保存するアプリを作ろうとしています。 ■変更前 りんご,赤,1, みかん,オレンジ,2 メロン,黄緑,3 ■変更後 1,赤,りんご, 2,オレンジ,みかん, 3,黄緑,メロン, 以下のような概略フローを考えてみたのですが、 (3)の処理を実行する場合、どのような実装すれば良いか分かりません。 ■概略フロー (1)1行ずつTextFieldParserで、string配列に読み込む (2)任意の列の値を左から順番を指定して並べ替える  No.3の列を左から1列目に指定⇒No.3の列を左から3列目に指定 (3)並べ替えた配列をカンマ区切りで再結合する どなたかご教示いただけると助かります。

  • PerlからOracleのストアドを呼びたいのですが、パラメータに配列は使えますか?

    Perl(5.005_03) からOracle(8i)のストアドを呼びたいのですが、パラメータに配列は使えますか? 使えるのなら、以下のようなストアドをPerl側から呼ぶには、どうすればよいでしょうか? ---------------------------------------------------------------------- /* 配列型 */ CREATE OR REPLACE PACKAGE text_util IS   TYPE vc_arr IS TABLE OF VARCHAR2(10)   INDEX BY BINARY_INTEGER; END; / /* 呼びたいストアド */ CREATE OR REPLACE PROCEDURE TEST_PROC ( v_DATA in text_util.vc_arr, i_IDX in INTEGER ) IS END; / ---------------------------------------------------------------------- よろしくお願いします。 【環境】sun4-solaris, apache

  • 文字列を分割するクラスについて

    住所のメソッドでの開発についてご質問がございます。 仕様 住所の配列は全角80(半角160)に格納される。 住所地名の途中で分割しないようにする。 80桁すべてに文字は格納されているときは20桁の4等分にする。 スペースで分割をおこなうようにする。 例1  実行前  札幌市 ○区 北○○○○○ 00-0-0-00      実行後  札幌市 ○区 北○○○○○,00-0-0-00,,      例1の場合20桁ずつ分割を考えると14桁目のスペースを利用してカンマ区切りで4つに分割 例2 実行後  あああああ いいいいい ううううう ええ     実行後  あああああ いいいいい ううううう ええ,,,     例2の場合文字がちょうど20桁なのでちょうどカンマ区切りで4等分  例3  実行前   あああああ いいいい ううううううううううう えええええ 0-00-000       実行後   あああああ いいいい,ううううううううううう えええええ,0-00-000,      例3の場合20文字だと区切りだと、うの領域の途中になるため      11桁目のスペースを利用して分割      そしてそこから20桁目を区切ろうとして次の区切りたい場所が      番地の途中になるため実行後のように、えで区切り4等分にカンマ区切り と基本的に住所分割をスペースを利用して住所の途中や番地の途中で 区切らないでカンマ区切りの4等分にするアルゴリズムを考えています。 private void 住所漢字(String 住所漢字, String 住所カナ, String 住民票住所漢字,PrintWriter out) { //(1)分割する文字列を生成 String str = new String(住所漢字); //(2)文字列をsplitメソッドで分割 String[] strAry = str.split(",", 0); { str = 住所漢字; } for (int i=0; i<strAry.length; i++) { } out.print(str.substring(0,20)+","+ str.substring(20,40) +","+ str.substring(40,60)+","+ str.substring(60,80)); }      現在は単純に全角80桁の配列に対して 20桁ずつの4等分に実行されるだけのプログラムになってます。 上記の例のような住所分割のアルゴリズムを開発する際 StringTokenizer st = new StringTokenizerのクラスは開発に有効でしょうか? また有効である場合のソース実行例の等のアドバイス、もしくは ほかに文字を分割するための便利なクラスがございましたら ご教授ください。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • Java