ExcelVBAからOracleストアド実行エラー

このQ&Aのポイント
  • ExcelVBAからOracleに接続し、ストアドを実行して複数行のデータを取得後、エクセルの各セルに取得データを設定するマクロを作成しています。しかし、コマンドのExecuteを行った後にレコードセットが取得できないエラーが発生しています。
  • ストアド自体はOracle側でエラーなく動作しており、カーソルで取得したデータをエクセル側に渡すためにそれ用のOutputの変数が必要なのか疑問に思っています。
  • どのようにすれば正常にレコードセットを取得できるのか、アドバイスをいただけると助かります。
回答を見る
  • ベストアンサー

ExcelVBAからOracleストアド実行

Excel:2010 Oracle:10g 接続:ADODB Oracleで質問すべきか、VB側にすべきか迷いましたが、こちらに質問させていただきます。 ExcelVBAからOracleに接続し、ストアドを実行して複数行のデータを取得後 エクセルの各セルに取得データを設定するマクロを作成しております。 コマンドのExecuteを行った後、レコードセットが取得できていないようで 「オブジェクトが閉じている場合は、操作は許可されません」 となってしまいます。 ストアド自身は、Oracle側でエラーなく動いています。 カーソルで取得したデータをエクセル側に渡すには、それ用のOutputの変数(配列?)が必要なのでしょうか? よろしくお願いいたします。 ストアドプロシージャ(一部SELECT文は長いため、省いています) -------------------- CREATE OR REPLACE PROCEDURE A.P930 ( varCD IN VARCHAR2, varDate IN VARCHAR2 ) AS CURSOR C_SIM IS SELECT CD, NAME FROM T WHERE CD = varCD AND CNTRCT_DATE = varDate; SIM_REC C_SIM%ROWTYPE; BEGIN OPEN C_SIM; LOOP FETCH C_SIM INTO SIM_REC; EXIT WHEN C_SIM%NOTFOUND; END LOOP; CLOSE C_SIM; END; / VBA側 Connection接続はOK -------------------- Sub LIST() 変数宣言等省いています Set myCmd = New ADODB.Command With myCmd .ActiveConnection = DBADOCon .CommandType = adCmdStoredProc .CommandText = "P930" .Parameters.Append .CreateParameter("varCD", adVarChar, adParamInput, 3, strLineCd) .Parameters.Append .CreateParameter("varDate", adVarChar, adParamInput, 6, strMonth) Set myRs = New ADODB.Recordset Set myRs = .Execute End With If myRs.RecordCount = 0 Then     ←ここでエラーになります 'エラーメッセージ表示 Exit Sub End I

  • Oracle
  • 回答数2
  • ありがとう数3

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

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

ん? > CREATE OR REPLACE PROCEDURE A.P930 > ( > varCD IN VARCHAR2, > varDate IN VARCHAR2 > ) は procedure (function じゃない)だし、out の引数もないから、 > Set myRs = .Execute ではなにもかえってこないんではないですか?? function の戻り値を ADO で得るためには、なんかくふうが要るようだ。 http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/as_s04.htm out で戻すなら、 http://www.progress-japan.co.jp/support/SupportLink/faq/technical/ProgrammingTips/programming/ ADODB.Command.Execute の戻り値は Command が SQL であるときのレコードセットじゃないかな?? ADOのしがらみがめんどうならば、ストアードで、ワークテーブルに書き込んで、 execute の戻り値をとらずに、ワークテーブルを直接見に行くかしたらいいんじゃないですかね?      

MAME2001
質問者

お礼

ありがとうございます! エラーの原因はわかりました。 カウントの仕方が違っていたようです。 やはり、outの引数がない場合は何も返ってこないんですかね? ストアドプロシージャとファンクションの違い、検索してみますね。 ワークテーブル等使うと楽そうですよね・・・ ただ、お客様からの仕様がストアドを作ってそれを見に行け という感じなので、もうちょっとやってみます!

その他の回答 (1)

  • nao-y
  • ベストアンサー率58% (111/190)
回答No.1

参考になるかどうかは分かりませんが… 参照URLはもうご覧になってますか? 参考URLはSQL Serverでのケースですが、 ストアド内で複数のSQL文を使っている場合に このエラーが出るようです。

参考URL:
http://nary.cocolog-nifty.com/blog/2009/12/sql-server-exce.html
MAME2001
質問者

お礼

まだきちんとテストできていませんが、自己解決です。 myRs.RecordCount ではなく、myCmd.RecoreCount のようです。

MAME2001
質問者

補足

nao-yさん、お返事ありがとうございます。 4時間くらいずっと検索し続けていましたので、こちらのページも拝見いたしました。 Oracleではまた違うような感じで・・・ SQL文は1つですが、UNIONのSQL文にしています。 ある条件で抽出し、UNIONでそれぞれの列のSUMを最後に取っています。 OracleのSQL文も久しぶりなのですが、やっとストアドのコンパイルエラーがなくなったと思ったら VBA側からのエラーがどうにも解決できず(>_<) カーソル自体あまりわかっていないのでそちらも合っているのか・・・

関連するQ&A

  • SQL Server 2000でのストアド

    現在,データベースの勉強中ですが,下記の内容で困っています。 ●SQL SERVER 2000のストアド CREATE PROCEDURE Strd_Test ( @aaa varchar(10), @bbb varchar(10), @rowcount int output, @msg varchar(100) output ) AS set nocount on begin select aaa,bbb from T_test where aaa=@aaa and bbb=@bbb end; select @rowcount=@@rowcount, @msg='検索に成功しました'; return GO ●Excel2003のVBA Private Sub btn1_Click() Set dbCN = New ADODB.Connection dbCN.Open "Provider=SQLOLEDB;" _ & "Data Source=*****,9999;" _ & "Initial Catalog=DB_Test;" _ & "User ID=sa;Password=" Set dbCOM = New ADODB.Command dbCOM.ActiveConnection = dbCN dbCOM.CommandType = adCmdStoredProc dbCOM.CommandText = "Strd_Test" dbCOM.Parameters.Refresh dbCOM.Parameters("@aaa") = "100" dbCOM.Parameters("@bbb") = "あいうえお" (1) ストアドの実行 (2) MsgBox "検索結果:" & dbCOM.Parameters("@rowcount").Value _ & vbCrLf & dbCOM.Parameters("@msg").Value (3) WorkSheets("Sheet1").Cells(1, 1).CopyFromRecordset dbRS dbRS.Close Set dbRS = Nothing Set dbCOM = Nothing End Sub ●こんな感じで,検索結果のレコードセットと, アウトプットパラメータの両方を取得したいのですが ExcelのVBAから,(1)のところで,   ・「dbCOM.Execute」とした場合には,    (2)でアウトプットパラメータが正常に返ってきます    (3)は,当然エラーです   ・「Set dbRS = dbCOM.Execute」とした場合には,    (2)でアウトプットパラメータが2つとも空です    (3)は正常にレコードセットを取得できます こうなってしまうのですが,レコードセットと アウトプットパラメータの両方を取得するためには, どこを修正すれば良いのでしょうか? どなたか,お力を貸してください。

  • VB.NETでADOでOracleのストアドを起動

    いつも楽しく勉強させていただいております。 環境はWindows Server 2008R2 DataCenter、データベースはOracle10G、開発ツールはVB.NET2015です。 このたびWindows Server 2003のVB6.0から上記の環境に乗せ換えているところです(Oracleのバージョンは変わりなし)。 最初にVB6.0からVB.NETへの変換はかけましたが、 なるべくVBのソースは変更しないという制約があります(テストのし直しが膨大になるので)。 VBとOracleはADOを使って接続しています。 ADOを使ってテーブルの読み書きはできるのですが、ストアドプロシージャの起動がうまくいきません。 具体的には入力パラメータはストアドに渡って処理も動くのですが、出力パラメータが返ってきません。 ストアドが正しく動くことはObjectBrowserで確認済みです。 下記のソースはVB6.0で動いていたものですが、VB.NET2015では二つの出力パラメータの値がNothingとなります。 (本来ならステータスとメッセージが返ります)。 VB.NET2015でADOでストアドを使うことは無理なのでしょうか。 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim Cnn As New ADODB.Connection Dim cmd As New ADODB.Command Dim Prm As New ADODB.Parameter Dim strMsg As String On Error GoTo Err_cmdExec_Click With Cnn .Provider = "MSDASQL" .ConnectionString = "DSN=DB1;" & "UID=abc;" & "PWD=efg" .Open() End With 'ストアドプロシージャ呼び出し設定&呼び出し With cmd .CommandTimeout = 0 'タイムアウト設定を無制限に .ActiveConnection = Cnn 'サーバー接続設定 .CommandText = "CHECK_PROC" 'ストアド名セット .CommandType = ADODB.CommandTypeEnum.adCmdStoredProc 'ストアドなのでadCmdStoredProc Prm = .CreateParameter("p_yyyymm", ADODB.DataTypeEnum.adChar, ADODB.ParameterDirectionEnum.adParamInput, 6, "201601") cmd.Parameters.Append(Prm) Prm = .CreateParameter("p_sts", ADODB.DataTypeEnum.adChar, ADODB.ParameterDirectionEnum.adParamOutput, 1) cmd.Parameters.Append(Prm) Prm = .CreateParameter("p_msg", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamOutput, 512) cmd.Parameters.Append(Prm) '実行 .Execute() '戻り値の判断&表示用メッセージ生成 If .Parameters.Item("p_sts").Value = "0" Then strMsg = "正常終了しました" Else strMsg = "異常終了しました" & vbCrLf & "ErrMsg=" & .Parameters.Item("p_msg").Value End If End With Exit_cmdExec_Click: '接続解除 Cnn.Close() 'Set Cnn = Nothing 'メッセージ表示 MsgBox(strMsg) Exit Sub Err_cmdExec_Click: 'ストアド以外の場所でのエラーなので、VBのErrの情報セット strMsg = "異常終了しました" & vbCrLf & "ErrNO=" & Err.Number & " ErrMsg=" & Err.Description Resume Exit_cmdExec_Click End Sub

  • ADO接続によるストアド

    あまりDB接続などに詳しくないので、 うまく説明できないと思いますがご了承下さい。 環境は Win2000+VB6+SQLSERVER2000+ADO2.5 やりたいことは、 SQLSERVERに設定してあるストアドがあります。 そのストアドをVB上から呼び出し結果を得たいわけです。 ストアドは、1つのパラメータを与えることで、 そのパラメータの最大値を取得してきます。 そして、データベース内では最大値が+1されているというものです。 現在 Dim adoCon As ADODB.Connection Dim adoCmn As ADODB.Command Dim adoRs As ADODB.Recordset ''DBに接続 Call DB接続関数(adoCon) Set adoCmn = New ADODB.Command Set adoRs = New ADODB.Recordset adoCmn.ActiveConnection = adoCon adoCmn.CommandText = "EXEC ストアド名 'パラメータ'" adoRs.Open adoCmn という状態で、ストアド自体は動作することができました。 しかし、最大値を取得することができません。 adoRsにはきちんとレコードセットが返ってきてない感じです。 どうすれば、最大値を取得できるでしょうか?

  • SQL ServerのストアドでUPDATEを実行すると・・・

    SQL Serverのストアド中でUPDATEを実行すると OUTパラメータの値が取得できなくなってしまいます。 何か制約などあるのでしょうか? わかる方よろしくお願いします。 1.UPDATE文をコメントアウトすると取得できます。 2.UPDATEは正常に実行されています。 /**参考ソース**/ /** 下記プログラムは、引数で取得した文字列に 連番テーブルの値をインクリメントした値と 結合しOUTパラメータに、連番テーブルには、 インクリメント結果をセットしています。 **/ CREATE procedure xml_get_document_seq @inDate varchar(14), @outSeq varchar(18) output as begin declare @Work varchar(4) declare @Seq varchar(18) declare @Number decimal(5) declare @SeqDoc varchar(18) if not exists(SELECT SEQ FROM XML_DOCUMENT_SEQ) begin INSERT INTO XML_DOCUMENT_SEQ(SEQ) VALUES(0) end set @Seq = ISNULL(@inDate,'') SELECT @Number = SEQ FROM XML_DOCUMENT_SEQ set @Number = @Number + 1 if @Number > 9999 begin  set @Number = 1 end set @Work = ISNULL(convert(varchar,@Number),'') set @SeqDoc= @Seq + replicate('0', 4 - datalength(@Work)) + @Work UPDATE XML_DOCUMENT_SEQ SET SEQ = @Number Set @outSeq = @SeqDoc return @Number end GO

  • ストアドプロシージャ結果のファイル出力について

    お世話になります。 以下のようにOracleにてストアドプロシージャを作成して、 それをAccessからコールしております。 そしてそのDBMS_OUTPUTの結果をファイル出力したいのですが、 試しに「sqlstmt = "BEGIN proc_SeikyuMeisai(:yyyymm); END;"」の部分を 「sqlstmt = "spool aaa.csv BEGIN proc_SeikyuMeisai(:yyyymm); END; spool off"」 や、ストアド側でspoolしてみましたがダメでした。 UTL_FILEを使うしかないのでしょうか? ご存じの方おられたらご教示いただけますでしょうか? 宜しくお願い致します。 【Access2003側】 ' セッションの作成 Set OraSession = CreateObject("OracleInProcServer.XOraSession") 'データベースへの接続 Set OraDatabase = OraSession.OpenDatabase("Hoge", "hoge/hoge", ORADB_DEFAULT) '■ ストアド実行 ■ sqlstmt = "BEGIN proc_SeikyuMeisai(:yyyymm); END;" 'バインド変数の設定 OraDatabase.Parameters.Add "yyyymm", 0, ORAPARM_INPUT OraDatabase.Parameters("yyyymm").serverType = ORATYPE_NUMBER '引数設定 OraDatabase.Parameters("yyyymm").value = Forms!F月次データ取込.txt日付1 'SQL文の実行 OraDatabase.ExecuteSQL sqlstmt DoCmd.Hourglass False '砂時計 'バインド変数の削除 OraDatabase.Parameters.Remove "yyyymm" '■ORACLEへの切断■ OraDatabase.Close 'オブジェクトの破棄 Set OraDatabase = Nothing Set OraSession = Nothing MsgBox "正常に出力されました。" 【Oracle10g】 Create or replace procedure Proc_SeikyuMeisai ( P1_YYYYMM IN number ) IS WK_KANID varchar2(10); WK_CODE varchar2(6); WK_SUU varchar2(12); WK_TEN varchar2(9); WK_KAI varchar2(2); -- カーソルタイプの定義 TYPE typeMyCursor IS REF CURSOR; -- カーソル変数の定義 curSeikyu typeMyCursor; curID varchar2(10); curMAX number; curMEISAI varchar2(1000); curTEN number; curKAI number; vSql varchar2(1000); BEGIN vSql := 'select KANNO, MEISAI_MAX, _MEISAI, HOU_TENSUU_KEI, TOTAL_KAISUU from SEIKYUUMEISAI' || P1_YYYYMM; -- カーソルオープン open curSeikyu for vSql; loop fetch curSeikyu into curID, curMAX, curMEISAI, curTEN, curKAI; exit when curSeikyu%NOTFOUND; WK_KANID := curID; for nLpCnt IN 1..curMAX loop WK_CODE := substrb(curMEISAI, 3, 6); WK_SUU := substrb(curMEISAI, 34, 12); WK_TEN := substrb(curMEISAI, 89, 9); WK_KAI := lpad(curKAI, 2, 0); dbms_output.put_line(WK_KANID || ',' || WK_CODE || ',' || WK_SUU || ',' || WK_TEN || ',' || WK_KAI); end loop; end loop; end; /

  • バッチで実行するVBScriptからのストアドプロシージャの実行

    VBスクリプトでDBにアクセスし、ストアドプロシージャを実行したいのですが、実行できなくて困っています。ADODB.Commandを使わずに、ADODB.Connection.ExecuteでCommandTextを実行するとレコードを取得することができるので、DBにコネクトすることはできているようなのですが、ストアドプロシージャを実行することができません。どなたか原因分かる方いらっしゃいますでしょうか。このスクリプトはASPではなく、バッチで実行します。よって参照設定ができないので、ComandTypeにadCmdStoredProcを値で入れるようにしています。サーバはWindows2003Server,DBはSQLServer2005です。よろしくお願いします。 Option Explicit On Error Resume Next Dim blnRetCode ' 戻り値 Dim objAdoCon ' ADO 接続 Dim objComm ' コマンドオブジェクト 'Dim return_value 'DBバックアップの成功、失敗の戻り値 ' ADO 定数の読み込み Set objAdoCon = WScript.CreateObject("ADODB.Connection") If Err.Number = 0 Then 'ADODBを使用してDBにアクセスする objAdoCon.ConnectionString = "Provider=SQLOLEDB.1;Password=aaaa;User ID=user2;Catalog=dbname;Data Source=192.168.8.2" objAdoCon.Open Set objComm = CreateObject("ADODB.Command") objComm.ActiveConnection = objAdoCon objComm.CommandType = 4 objComm.CommandText = "ExportData" objComm.Execute If (Err.Number <> 0) Then MsgBox Err.Number End If objAdoCon.Close End If Set objComm = Nothing Set objAdoCon = Nothing

  • 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

  • ストアドプロシージャの戻り値が取得できない

    ストアドプロシージャの戻り値が取得できない ストアドプロシージャ内でSelectとUpdateを行い、設定した戻り値をリターンしたいのです。 ついでにSelectとした複数行の結果の読み込みもしたいのですが。 Dim cmd As New System.Data.SqlClient.SqlCommand Dim i As Integer Dim readerA As System.Data.SqlClient.SqlDataReader cmd.CommandType = Data.CommandType.StoredProcedure cmd.CommandText = "SP名" cmd.Parameters.Add("A", System.Data.SqlDbType.Int) cmd.Parameters("A").Direction = System.Data.ParameterDirection.ReturnValue readerA = cmd.ExecuteReader() i = cmd.Parameters("A").Value if (i = 0) Then 処理 End If While readerA.Read() 処理 End While 上記でSelectした結果をreaderA("カラム名") で読みこめているのですが、戻り値Aの値が取得できていません。 ウォッチ式でcmd.Parameters("A").Valueを見るとNothingになっています。 ちなみに、違うストアドを実行しているところでは戻り値は取得できています。。。 ストアドがおかしいんでしょうか。Selectの取得結果も見ようとしているのがまずいのでしょうか。 環境はvb.net、SQLServer2005です。

  • postgres ストアドファンクションないのレコードの取得について

    質問させていただきます pg/plsqlのストアドファンクション内で 受け取った引数を sql := select * from hoge; FOR rec IN EXECUTE sql LOOP return rec.col;     <<<この部分で END LOOP; return; rec.引数名のようにして 引数から取得した 列を指定したいのですが、そのまま入れると そのような列はありませんと言うような返事を 返されてしまいます。 うまくやる方法はないものでしょうか? よろしくお願いします。

  • ループしてUPDATEするストアドについて

    よろしくお願いいたします。 表題の件どうしてもわからなかったので、皆様どうかご教示お願いいたします。 下記ストアドを作成いたしました。 内容としては UPDATE文 「ユーザー情報 SET 通知f1 = 1 WHERE (送信先1 IS NOT NULL) AND (送信先1 <> '')」 の 通知fが1から30 送信先が1から30 をループして実行するといったいたってシンプルなのもです。 が、なんか上手くいかないんです。 ALTER PROCEDURE [dbo].[test] AS DECLARE @Counter int DECLARE @StrFileds1 varchar(1000) DECLARE @StrFileds2 varchar(1000) SET NOCOUNT ON SET @Counter = 1 SET @StrFileds1='' SET @StrFileds2='' WHILE @Counter <= 30 BEGIN SET @StrFileds1='通知f'+Convert(varchar,@Counter) SET @StrFileds2='送信先'+Convert(varchar,@Counter) SET @Counter=@Counter+1 BEGIN UPDATE ユーザー情報 SET @StrFileds1 = 1 WHERE (@StrFileds2 IS NOT NULL) AND (@StrFileds2 <> '') END END