ストアドプロシジャと変数のセットについて

このQ&Aのポイント
  • SQL SERVER 2005を利用し、ストアドプロシージャを作成しております。あるストアドでwk_hizukeというテーブルから、tokuisakicodeとdenpyouhizukeを変数@tokucdへ送り、別のストアドを呼び出し@hizuke1を戻り値としてメインのストアドへ戻し、@hizuke1を上記テーブルのdenpyouhizukeへ格納したいというのが行ないたいことです。
  • wk_hizukeというテーブルには複数のレコードが入っており、そのレコードを一件ずつ読みながら、上記の処理を行ないたいと考えております。
  • 構文の記述がエラーとなっており、原因を特定できずに困っています。アドバイスをお願いします。
回答を見る
  • ベストアンサー

ストアドプロシジャと変数のセットについて

SQL SERVER 2005を利用し、ストアドプロシージャを作成しております。 あるストアドでwk_hizukeというテーブル(下記の構成)から、tokuisakicode tokuisakicode int, denpyouhizuke smalldatetime を変数@tokucdへ送り、別のストアドを呼び出し@hizuke1を戻り値として メインのストアドへ戻し、@hizuke1を上記テーブルのdenpyouhizukeへ格 納したいというのが行ないたいことです。 wk_hizukeというテーブルには複数のレコードが入っており、そのレコード を一件ずつ読みながら、上記の処理を行ないたいと考えております。 select tokuisakicode set @tokucd = tokuisakicode exec sp_hizukesanshutu @tokucd , @hizuke1 output , from wk_hizuke このような構文を記述してみたのですが、エラーとなってしまいました。 根本的に考え違いをしているのかと思い、いろいろ調べてみたのです が、妥当と思われる構文を見出すことができずにおる次第です。 アドバイスいただければ幸いです。宜しくお願い致します。

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

  • ベストアンサー
  • utakataXEX
  • ベストアンサー率69% (711/1018)
回答No.1

大体やりたい事のイメージはつかめます。 >wk_hizukeというテーブルには複数のレコードが入っており、そのレコード >を一件ずつ読みながら、上記の処理を行ないたいと考えております。 (略) >が、妥当と思われる構文を見出すことができずにおる次第です。 その場合は、「カーソル(CURSOR)」を使用します。 ・カーソルをオープンし、それを1行ずつ読み込んでループの中で処理する と言う方法です。 カーソルを定義して、オープンした後、そのカーソルを1行づつ処理します。 カーソルLOOPで1行読み込む事を「フェッチ(FETCH)」と言います。 本家MicrosoftのMSDN - FETCH (Transact-SQL) http://msdn.microsoft.com/ja-jp/library/ms180152.aspx @IT:ストアドプロシージャによる繰り返し処理 http://www.atmarkit.co.jp/fnetwork/rensai/sql22/sql1.html ストアドプロシージャの花形“カーソル”を使おう - @IT http://www.atmarkit.co.jp/fdb/rensai/tsql11/tsql11_1.html 肝の部分だけ簡潔に書くとこんな感じです。 (sp_hizukesanshutuに必要な変数定義や構文の確かさ等々は省略しています) -- カーソル定義 DECLARE wk_hizuke_cur CURSOR FOR SELECT tokuisakicode FROM wk_hizuke; -- カーソルオープン OPEN wk_hizuke_cur; -- 1行先読み FETCH NEXT FROM wk_hizuke_cur; --↓ ↓ ↓ ↓ ↓ LOOP処理開始(データが存在する間ループする) WHILE @@FETCH_STATUS = 0 BEGIN -- ↓1行読んだ後の処理をここに記述する -- ストアド呼び出し exec sp_hizukesanshutu @tokucd , @hizuke1 output; -- おそらくこの後、output の hizuke1 を使って何か処理するんでしょうね? -- 更に1行追加で読み込み(データがあれば再度ストアド呼び出しを行なう) FETCH NEXT FROM wk_hizuke_cur; END --↑ ↑ ↑ ↑ ↑ LOOP処理終了 -- カーソルクローズ CLOSE wk_hizuke_cur; --最後のおなじない DEALLOCATE wk_hizuke_cur; この手の処理の王道が、上記のカーソルでLOOPする方法です。 バルク的にガッと一発で処理する方法と言うのも、アレコレいじれば多分可能ですが、output を使って何か処理するのであれば、バルク的な処理はできない、と言う要件ですよね、おそらく。 いずれにせよ、まずは王道を先に身に付けた方がよろしいかと思います。

takazou
質問者

お礼

ご回答いただき、どうもありがとうございました。 大変わかりやすく、参考になりました。 さっそく試してみたいと思っております。記していただいたURLも参照させていただきます。 ありがとうございました。

関連するQ&A

  • ストアドから得られるレコードセットを、別のストアドで利用したい

    現在、実行するとあるレコードセット(1行1列のみ)を返すストアドプロシージャProc_Aがありますが、このプロシージャを実行して得られる結果を、 別のプロシージャProc_Bで、以下のような形で使用したいと考えています。 ただし、Case文内部でのストアドの実行や、変数へのストアドの実行結果の代入を試しましたが、どちらもうまくいっていません。 なにか、よい解決策があれば、教えていただければ、と思います。 パターンA) Case内部で直接実行 select case Table_A.param_1 when 0 then Exec Proc_A '***','**' else '' end パターンB)いったんパラメータとして取得 declare @values as char(10) execute sp_executesql N'@values = Proc_A ''***'',''**''', N'@values char(10) OUTPUT', @values OUTPUT

  • PL/SQLに関して

    PL/SQLに関しての質問です。 1、プロシージャの内部にファンクションをネストするなどということはできるのでしょうか? (内部ファンクションのような感じで) 2、プロシージャからファンクションを呼び出し、ファンクションの戻り値をレコード型変数にした場合、ファンクションでSELECTしたレコード件数が0件であった場合、例外ブロックのWHEN no_data・・・THEN で、RETURN NULLで戻すことはできるでしょうか? (呼び出し側で、レコード型変数にNULLを代入できますか?) 3、ObjectBrowserからストアドプロシージャを実行するとき、引数ありのストアドプロシージャを実行する方法を教えてください。(または参考WEBサイトを教えてください。) いずれも、試す環境が今ないため、ご回答のほどよろしくお願いします。

  • VB6 + OO4O プロシージャの実行&複数行を受け取る方法

    VB6 + OO4O プロシージャの実行&複数行を受け取る方法 現在、VB6でOracleデータベースを操作しようと試みている最中で、 OO4Oで接続しています。 (表現誤っているかもしれません。。。) Oracleは今回初めてで、今まではSQLserverだったのですが、 SQLserverで、  1.ストアドを実行(パラメータあり)  2.レコードセット(複数行)を受け取る  3.ループで全件処理   ・・・ というような処理をしていました。 たとえば、あるテーブルの、ある条件に一致したレコード(複数あり)を全件取得 など。 「引数を渡してストアドプロシージャを実行し、複数行を結果として受け取る」ということがしたく、 Oracleでどのように実現させるかを調べてみたのですが、 「SQL文を記述し、受け取る」  例)strSQL = "select * from tbl"    Set OraDynaset = OraDatabase.CreateDynaset(strSQL, 0) というようなサンプルしか見つけられませんでした。 where句で条件を記述すれば同じなのかもしれませんが、 そういったこまごました記述をストアドプロシージャに記載しておき、 呼び出す際はパラメータだけ指定する、ということを想定しています。 ストアドを実行するサンプルは複数見つけたのですが、戻り値が1つのみか、戻り値なしのもので、 複数行を結果として受け取るようなサンプルが見あたりませんでした。 ストアド(PL/SQL)も作成してみたのですが、 単純に  select * from TBL; とするとエラーで、  select * BULK COLLECT INTO vTBl from TBL;  for i in 1 .. vTBl.count loop   -- 全レコードの項目「name」を表示する。   dbms_output.put_line(vTBl(i).name);  end loop; というように1件1件処理させていく方法しか見つけれませんでした。 Oracleのストアドは、今までのSQLServerの考え方はいけないのでしょうか? 調べるとしたら、どのような単語で調べたらよろしいでしょうか? 「VB6」「oo4o」「複数行」「プロシージャ」など、いろいろ努力はしたつもりなのですが。。。 ご指導よろしくお願いいたします。

  • ORA-01722: 数値が無効です

    よろしくお願いします ORACLEのストアドプロシージャを実行した際、 上記のような結果が出ました。 調査した結果、ストアドプロシージャ内でのSQLで SELECT ・・・ FROM A_table WHERE A_table.a_date > 20050120 ; のようなものがあり、 A_tableのa_dateカラムが文字列型であり、 数値型との比較を行っているための エラーと確認が取れました。 しかし、 私が確認をとったのはシステムのテスト環境なのですが、 本番の環境はまったく同じプロシージャで エラーが出ていないようなのです。 なぜなのでしょうか??? 考えられる原因がある方がいらっしゃいましたら 是非教えてください。 よろしくお願いいたします。

  • ストアドプロシージャの実行

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

  • SQLServer Agentサービスの稼動状況の取得

    お世話になります。 SQLServer Agentサービスの稼動状況を取得する方法で困っています。 http://questionbox.jp.msn.com/qa3176474.html 上記URLを参考に exec master.dbo.xp_servicecontrol 'QUERYSTATE', 'SQLServerAgent' でステータスがチェックできることがわかったのですが、 DECLARE @<変数> <データ型> EXECUTE <ストアドプロシージャ> [<引数>...], @<変数> OUTPUT SELECT @<変数> '<フィールド名>' に当てはめて戻り値を取得することができません。 稼動状況を変数で取得するよい方法がありませんでしょうか。 よろしくお願いいたします。

  • プロシージャの戻り値を取得する方法

    perlからSQLPLUS->プロシージャを実行してその戻り値を取得。 戻り値が0なら次の処理へ、0以外ならエラー処理へというようなことをやりたいと思っています。 perlの実行コマンドは以下。 $sqlcmd = "sqlplus$DBUSER$PASS\@DB_ALIAS\@$SQLFILE $OUTFILE"; $sql_ret = system("$sqlcmd") >>8; この$sql_retにプロシージャの戻り値が入るようにしたいのです。 プロシージャを実行する$SQLFILEは以下のようなSQLです。 --------------------------------------------------- set serveroutput on WHENEVER SQLERROR EXIT 1 spool &1; DECLARE RetVal NUMBER; BEGIN RetVal := 実行ストアドファンクション; END; / spool off; EXIT SQL.SQLCODE; ---------------------------------------------- エラーが起きたときにファンクションは1を返すようにしているのですが、 それがSQLPLUSの実行結果の戻り値に反映されません。 どうしたらいいのでしょうか? よろしくお願いします。

  • SQLサーバーはテーブルの置き場として使えるのでしょうか?

    SQLサーバー初心者です。 アクセスのMDBファイルのリンクテーブルとしてSQLサーバーを使う場合、 クエリとかストアドプロシージャー(?)などの機能があるみたいですが よくわからないので 本当にただテーブルの置き場としてSQLサーバーを使うことはできるのでしょうか? 宜しくお願い致します。

  • テーブルが存在していたらDROPしてからCREATEするには?

    作成しようとするテーブルが既に存在している場合 一度DROP TABLEを行いたくて、以下のSQLを作成したのですが 削除が実行されません。 そもそものやり方自体が間違っているのでしょうか? 実行後のメッセージは テーブルが存在しなかった場合→コマンドは正常に完了しました。 テーブルが存在した場合→データベースにオブジェクト名 'SLIP_ITEMXX' が既に存在します。 と、表示されます。 --テーブルが存在した場合削除する ※ストアド使用 CREATE PROCEDURE SP_SLIP_ITEMXX AS DECLARE @TableName varchar DECLARE @Sql varchar set @TableName = 'SLIP_ITEMXX' SET @Sql = 'if exists (select * from dbo.sysobjects where id = object_id(N' + @TableName + ') ' + 'DROP TABLE ' + @TableName EXEC(@Sql) GO --テーブル生成 CREATE TABLE SLIP_ITEMXX( [slip_no] [int] NOT NULL ) GO --ストアド削除 DROP PROCEDURE SP_SLIP_ITEMXX GO

  • T-SQLの sp_executesql について

    SQL-Serverでストアドプロシージャを作っています。 EXEC sp_executesql で検索結果をテーブル型変数に格納したいですができるのでしょうか。動的にSQLを発行し、結果を格納する必要がありますのでEXEC sp_executesqlを使わざる得ない状況です。下記にそのサンプルがあります。 Declare @tblAA Table(NO int) declare @strSQL nVarChar(1000) set @strSQL = '' set @strSQL = @strSQL + ' Insert into @tblAA' set @strSQL = @strSQL + ' Select NO from TBLBango' EXEC sp_executesql @strSQL ,N'@tblAA table(No int) OUTPUT', @tblAA OUTPUT Select * from @tblAA これを実行すろと「変数 '@tblAA' を宣言する必要があります。」というエラーがでます。 解決方法を分かる方教えてください。