• 締切済み

VBからストアドプロシジャを実行

VBからストアドプロシジャを実行すると、下記のエラーが発生します。 型 'System.InvalidOperationException' の初回例外が Oracle.DataAccess.dll で発生しました オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 テーブルとプロシジャはシステムユーザの管理下にあり、一般ユーザで接続しています。直接SQLを実行すると正しく動作しています。以下にコードを示しますが、どこに問題があるのでしょうか。システムユーザの管理下にある事より直接SQLを実行した時と同じ様に「system.xxx」としても結果は変わりませんでした。あと、一般ユーザにはconnectとselectの権限のみ与えています。 ■VB側のコード 'オブジェクト Dim oraCmd As New OracleCommand 'PL/SQLパラメタ Dim oraPrm1 As OracleParameter Dim oraPrm2 As OracleParameter ' 実行タイプ(PL/SQLとして実行) oraCmd.CommandType = CommandType.StoredProcedure ' プロシージャ名 oraCmd.CommandText = "GETNAME" ' パラメータクリア oraCmd.Parameters.Clear() ' 1つ目のパラメータ( IN なのでデータセット ) oraPrm1 = oraCmd.Parameters.Add("PM_STRING", OracleDbType.Varchar2) oraPrm1.Value = "2001" oraPrm1.Direction = ParameterDirection.Input ' 2つ目のパラメータ( OUT なので、Direction プロパティにセット ) oraPrm2 = oraCmd.Parameters.Add("PM_NUMBER", OracleDbType.Int16) oraPrm2.Direction = ParameterDirection.Output Try ' 結果を受け取り、後で処理する oraCmd.ExecuteNonQuery() Catch ex As Exception conn.Close() Console.WriteLine(ex.Message) Return End Try Console.WriteLine(oraPrm2.Value.GetType()) ■ストアドプロシジャ CREATE OR REPLACE PROCEDURE GETNAME (IN1 IN NUMBER, OUT1 OUT VARCHAR2) AS BEGIN select NAME INTO OUT1 from TEST where CODE = IN1; END GETNAME;

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

みんなの回答

noname#212058
noname#212058
回答No.3

> 何か余計酷くなったみたいですが、PL/SQLでエラーが > 出たので少しは先に進んだのでしょうか? 大きく前進しています。先のコードでは ORACLE にコマンド実行すらできていませんでしたが、今回は実行はできていますので。 > PLS-00201: 識別子GETNAMEを宣言してください。 GETNAME というストアドが存在しないか、実行権限がないと発生します。おそらく接続ユーザにストアドの実行権限がないのかと。

saki0113
質問者

補足

色々ありがとうございました。 とりあえずPL/SQLは実行できるようになりましたが 今度は下記のエラーが出ます。 ORA-06502: PL/SQL: 数値または値のエラーが発生しました ググったらNULLがどうたらと書かれているのですが、 どこがNULLになっているのか分かりません。 ' パラメータクリア oraCmd.Parameters.Clear() ' 1つ目のパラメータ(INなのでvalueプロパティにデータセット) oraPrm1 = oraCmd.Parameters.Add("PM_NUMBER", OracleDbType.Int16) oraPrm1.Value = 2001 ' 2つ目のパラメータ(OUTなのでDirectionプロパティにセット) oraPrm2 = oraCmd.Parameters.Add("PM_STRING", OracleDbType.Varchar2) oraPrm2.Direction = ParameterDirection.Output create or replace PROCEDURE GETNAME (PM_NUMBER IN NUMBER, PM_STRING OUT VARCHAR2) AS BEGIN select NAME INTO PM_STRING from system.TEST where CODE = PM_NUMBER; END GETNAME;

noname#212058
noname#212058
回答No.2

Dim conn As New OracleConnection(conStr) oraCmd.Connection = conn; このふたつのコードは、全く別のモノです。 ・上は OracleConnection のインスタンスを作るもの ・下は『作った OracleConnection を、oraCmd に設定するもの』 です。下のコードが Dim oraCmd As New OracleCommand の下に書かれていないので、問題が発生しています。試しに書いてみてください。

saki0113
質問者

補足

Dim conn As New OracleConnection(conStr) Dim oraCmd As New OracleCommand oraCmd.Connection = conn 何か余計酷くなったみたいですが、PL/SQLでエラーが出たので少しは先に進んだのでしょうか? 型 'Oracle.DataAccess.Client.OracleException' の初回例外が Oracle.DataAccess.dll で発生しました ORA-06550: 行1、列7: PLS-00201: 識別子GETNAMEを宣言してください。 ORA-06550: 行1、列7: PL/SQL: Statement ignored 追加する前もconn.Open()は正常に動作しているので、別の原因の様な気もするのですが…

noname#212058
noname#212058
回答No.1

oraCmd にコネクションが設定されていないようですが。 oraCmd.Connection = conn; の実行が抜けてるんじゃないですか?

saki0113
質問者

補足

今回の問題とは直接関係無い(というかそれが抜けていたら直接SQLを実行しても動かないはず)と思って書いていませんでした。実際はその前に下記のコードがあります。 Dim conn As New OracleConnection(conStr)

関連するQ&A

  • VB6でのPL/SQLの実行について

    現在VB6(SP6)でORACLEのデータベースに接続後、プロシージャを実行してOUTのパラメータを取得したいと思ってプログラムを作っております。 ORACLEへの接続はいろいろ調べてできたのですが、プロシージャの実行(呼び出し)のしかたがわからず困っております。 PL/SQL(プロシージャ名"TEST_DATA") out1 = TEST(OUTパラメータ1) out2 = これはテストです。(OUTパラメータ2) VB6(SP6) Dim OraSession As OraSession Dim OraDatabase As OraDatabase Dim OraDynaset As OraDynaset Dim P1 AS String Dim P2AS String '接続処理 Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.OpenDatabase("TEST", "TEST/TEST DB_DEFAULT) OraSession.BeginTrans 'ここでPL/SQLを実行して、パラーメタを取得したいです。 '取得したパラメータをセット P1 = パラメータ1(TEST) P2 = パラメータ1(これはテストです。) OraSession.CommitTrans '結果表示 Call MsgBox(P1 & "結果" & P2) ご教授のほどをお願いいたします。

  • VB2010からPROCEDUREを実行でエラー

    VB2010を使っています。 Oracleのプロシージャを呼び出しするのですが、 以下のエラーが出て困っています。 ORA-06550:行1、列7: PLS-00801:内部エラー[22503] ORA-06550:行1、列7: PL/SQL:Statement ignored 実際のPG Public Function ORA_EXECUTE(ByVal strSQL As String) As Boolean ' データ格納領域の初期化 Dim v_return_flg As Boolean Dim Ora_Cnn_bk As OracleConnection Dim Ora_Cmd_bk As OracleCommand ' Oracle接続情報の初期化 Ora_Cnn_bk = New OracleConnection Ora_Cmd_bk = New OracleCommand ' Oracleへのコネクションの確立 Ora_Cnn_bk.ConnectionString = "User Id=(ユーザ名); Password=(パスワード); Data Source=(接続文字列)" & "; Pooling=false" Ora_Cnn_bk.Open() v_return_flg = False Try Dim oTYPE_CHAR As OracleDbType = OracleDbType.Char Dim oPARM_OUTPUT = ParameterDirection.Output 'バインド変数のセット Ora_Cmd_bk.Parameters.Add("AAA", oTYPE_CHAR) Ora_Cmd_bk.Parameters("AAA").Value = " " Ora_Cmd_bk.Parameters("AAA").Direction = oPARM_OUTPUT Ora_Cmd_bk.Parameters("AAA").OracleDbType = oTYPE_CHAR 'ストアドプロシージャ実行 Ora_Cmd_bk.CommandType = CommandType.StoredProcedure Ora_Cmd_bk.CommandText = strSQL Ora_Cmd_bk.Connection = Ora_Cnn_bk Ora_Cmd_bk.ExecuteNonQuery() Catch ex As Exception MessageBox.Show("SQL(" + strSQL + ")" + Chr(13) + ex.Message, "確認", MessageBoxButtons.OK) Finally ' コネクションを閉じる Ora_Cnn_bk.Close() ' Oracle接続情報のクリア Ora_Cnn_bk = Nothing Ora_Cmd_bk = Nothing End Try ' データ返却 Return v_return_flg End Function Oracle側のプロシージャは、別PGで使用していて C++からアクセスし使える状態です。 お分かりになる方教えてください。 m(_ _)m

  • VB6でのSQL実行について

    VB6でのSQL実行について VB6でのSQL実行について困っています。 SQL文を作成し、ダイナセットで実行している最中にも 再度別のSQL文をダイナセットで実行することは可能なのでしょうか? 言語はVB6.0、DBはOracle9iを使用しています。 イメージ的にはこんな使い方をしたいです。 dim lngRecordRow1 as long 'レコード数1 dim lngRecordRow2 as long 'レコード数2 dim OraDynaset1 As OraDynaset dim OraDynaset2 As OraDynaset dim strSQL as string 'SQL文 dim lngCnt1 as long 'ループカウンタ1 dim lngCnt2 as long 'ループカウンタ2 strSQL= ---SQL文作成1回目--- Set OraDynaset1 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行1回目 lngRecordRow1 = OraDynaset1.RecordCount for lngCnt1 = 1 to lngRecordRow1 '--- 処理 --- strSQL= ---SQL文作成2回目--- Set OraDynaset2 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行2回目 lngRecordRow2 = OraDynaset2.RecordCount for lngCnt2 = 1 to lngRecordRow2 '--- 処理 --- next lngCnt2 next lngCnt1 1回目で取得したSQL実行結果を行単位でループをまわしつつ、1回目で取得したレコードの結果を条件に使用して別のSQL文を作成し、ループをまわしている最中に実行したいです。 その際、2回目のSQLの結果が2レコード以上の場合、さらにループをまわして条件判別をしたいです。 かなり困っています。回答待ってます。

  • VB.Net SqlCommand 共通に

    お世話になります。 VB.Net 駆け出しの者です。 SqlCommand を使いストアドプロシジャーを実行して戻り値を DateSet にするような関数はプログラムを作っていくと、かなり多数になるようになりました。接続文字列だったり、いろいろ同じような記述が続いているなと思っておりました。 そこで、以下のような関数を作り、この部分を使いまわせないものかと思っております。 ストアドプロシジャーの名前や、そのほか必要な部分の文字はすべて変数にして、なんとか使えないのかなと思っているのですが、問題なのは、パラメータの部分でうまくいかないのです。 パラメータの部分だけ別関数にして、なんとかねじこめないかなと思っているのですが・・・ そもそもこういうやり方が正しいのかどうかもわからないのですが、その辺りも含めご教授いただければ幸いでございます。 何卒よろしくお願いいたします。 Public Function CommonDataSet(ByVal NameStored As String, ByVal CMDPara As SqlCommand, ByVal BasicTableName As String, ByVal ErrStr As String, ByVal ErrStrCaption As String) As DataSet     Dim SQLCon As SqlConnection = New SqlConnection(CMO.GetConnectStrings())     Try       CMDPara = New SqlCommand(NameStored, SQLCon)       CMDPara.CommandType = CommandType.StoredProcedure       SQLCon.Open()       Dim custDA As SqlDataAdapter = New SqlDataAdapter       Dim custDS As DataSet = New DataSet       ’この部分で下記の関数でパラメータを設定したいのですが、うまくいきません       custDA.SelectCommand = CMDPara       custDA.Fill(custDS, BasicTableName)       CommonDataSet = custDS     Catch ex As Exception       Err.Raise(Err.Number)       MessageBox.Show(ErrStr, ErrStrCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning)       CommonDataSet = Nothing     End Try     If SQLCon.State <> ConnectionState.Closed Then       SQLCon.Close()       SQLCon.Dispose()     End If End Function パラメータを設定する関数 上の関数の引数として設定したいのです  ByVal CMDPara As SqlCommand の部分のパラメータとして Private Function CommonPara(CMD As SqlCommand) As SqlCommand     CMD.Parameters.Clear()     CMD.Parameters.Add(New SqlParameter(パラメータ1の記述)     CMD.Parameters.Add(New SqlParameter(パラメータ2の記述)     CMD.Parameters.Add(New SqlParameter(パラメータ3の記述)     CommonPara = CMD End Function

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

    ストアドプロシージャの戻り値が取得できない ストアドプロシージャ内で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です。

  • VB2008とObjectBlowser9の連動について

    お世話になります。 先日、こちらのサイトでTextBoxの暗号化について質問させていただいたのですが、 現在、ObjectBlowser9のファンクションに、暗号化の dbms_obfuscation_toolkit.desencrypt( input_string => orgstr, key_string => keystr, encrypted_string => encstr ); を作成し、VBからそのファンクションに接続しようと考えております。 ですが、 Using con As New OracleConnection(builder.ConnectionString) con.Open()  Using cmd As New OracleCommand With cmd .Connection = con .CommandType = CommandType.StoredProcedure .CommandText = "CON_PASS_ANGO" .Parameters.Add("keystr", OracleType.VarChar).Value = keystr .Parameters.Add("orgstr", OracleType.VarChar).Value = orgstr .Parameters.Add("encstr", OracleType.VarChar).Direction = _ ParameterDirection.ReturnValue .ExecuteNonQuery() MessageBox.Show(String.Format("{0}X{1}={2}", _    keystr, orgstr, .Parameters("encstr").Value)) End With End Using End Using と記述したところ、 .Parameters.Add("encstr", OracleType.VarChar).Direction のところで、 パラメータ 'encstr': 可変長データ型 : String のサイズが設定されていません。というエラーが出てしまいます。 エラーの意味も調べたのですがいまいち理解できず、停滞しているところです。どなたか解決策をご提示願えないでしょうか、 よろしくお願いします。

  • 【初心者です】SQLPLUSでのバッチ実行時の引数(パラメータ)指定について

    SQLPLUSは詳しくなく、躓いてしまいました。 ストアドプロシジャを「aaa.sql」として作成して、 C直下に配置しました。 それをSQLPLUSから実行したいのですが、 パラメータの指定がうまくいきません。 SQL> @C:\aaa('BBB','CCC'); 上記のようにしても「ファイルがオープンできません」 と表示されてしまいます。 「(~)」を取り外して実行すると、動くみたいですので パラメータの指定が間違っているみたいです。 よろしくお願いします。

  • VB DB更新時にパラメーターへ値のセット

    データベースの更新についてご指導下さい。 VB2010からSQLサーバーのデータベースに接続しております。 dataAdapter.Updateによりデータベースを更新する際の パラメーターへ値をセットする方法を教えて下さい。 テーブル名Test Code Name ------------ A   Suzuki 希望する処理 テキストボックスに入力された名前に変更 例) Suzuki → Yamada ○フォームの変数として定義 Dim dataAdapter As New SqlDataAdapter Dim dataSet As New DataSet ○FormLoad時にSelectCommandとUpdateCommandを設定 Dim SQL As String = "" Dim command As SqlCommand Dim connection As SqlConnection = New SqlConnection(~) SQL = "SELECT * FROM Test WHERE Code = @code " command = New SqlCommand(SQL, connection) dataAdapter.SelectCommand = command dataAdapter.SelectCommand.Parameters.Add("@code", SqlDbType.Char) SQL = "UPDATE Test SET Name = @name WHERE Code = @code" command = New SqlCommand(SQL, connection) dataAdapter.UpdateCommand = command dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char) dataAdapter.UpdateCommand.Parameters.Add("@name", SqlDbType.Text, 50) ○データ表示時にはこれで表示されました。 dataAdapter.SelectCommand.Parameters.Item("@code").Value = ComboBoxCode.text dataAdapter.Fill(dataSet) ○このSelectCommandを参考にこのように書いて見たのですが更新されません。 dataAdapter.UpdateCommand.Parameters.Item("@code").Value = ComboBoxCode.Text dataAdapter.UpdateCommand.Parameters.Item("@name").Value = TextBoxName.Text dataAdapter.Update(dataSet) どのようにしたら実行時にパラメーター化したところへデータをセットできるのでしょうか? データセットに値が入っていないのでは?と予想したのですが…。

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

    asp.net から sqlserver のストアドプロシージャを実行させる勉強をしています。 作成されているはずのストアドプロシージャを実行できずに困っています。 webformにテキストボックス、ボタン、データグリッドを貼り付け、ストアドプロシージャを作成し下記のプログラムを実行させるのですが上手くいきません。 (テキストボックスに任意で入力された数値のデータをボタンを押すと表示するものです) <エラー内容>→ ストアド プロシージャ 'proc1' が見つかりませんでした Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim cn As New SqlConnection Dim cmd As New SqlCommand cn.ConnectionString = "接続文字列" cmd.Connection = cn cmd.CommandText = "proc1" cmd.CommandType = System.Data.CommandType.StoredProcedure Dim p1 As SqlParameter = cmd.Parameters.Add("@param1", System.Data.SqlDbType.Int) p1.Value = TextBox1.Text cn.Open() Dim dr As SqlDataReader = cmd.ExecuteReader DataGrid2.DataSource = dr DataGrid2.DataBind() dr.Close() cn.Close() end sub ストアドproc1(場所:Northwind)の内容↓ CREATE procedure proc1 @param1 int as select * from products where categoryID=@param1 どなたか原因のわかる方がいれば、宜しくお願いします。

  • プロシージャまたは関数の引数が多すぎますのエラー

    お世話になります。 下記のコードを実行すると プロシージャまたは関数 spTest の引数が多すぎます どこが悪いのかご教示お願いいたします。 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim i As Integer Dim conn As New SqlConnection(connstr) Dim cmd As New SqlCommand conn.Open() cmd.Connection = conn cmd.CommandText = "Delete Table2" cmd.CommandType = CommandType.Text Debug.WriteLine(cmd.ExecuteNonQuery()) For i = 1 To 100 spTest(cmd, i) Next conn.Close() End Sub sub spTest(ByRef cmd As SqlCommand, ByVal intID As Integer) Dim param As SqlParameter With cmd .CommandType = CommandType.StoredProcedure .CommandText = "spTest" param = .Parameters.Add(New _ SqlParameter("@ID", SqlDbType.Int)) param.Value = intID .ExecuteNonQuery()    ''''' ここで2回目からエラーが発生します End With End sub