DOBON.NET DOBON.NETプログラミング掲示板過去ログ

VB.NET2010ExpでADODB.Parameters.Appendが異常終了する

環境/言語:[OS : Windows XP / 言語 : Visual Basic .NET]
分類:[.NET]

【解決したい問題】

vb.net2010 express版を使用して、ADODBを使いオラクルへ接続を行っています。

引数付のストアドプロシージャを実行する為にADODB.commandクラスを利用してADODB.parametersコレクションをappendで追加をしようとしているのですが、以下のエラーで例外が発生してしまいます。

↓↓↓↓↓ 例外内容 ↓↓↓↓↓
型 'System.__ComObject' の COM オブジェクトをクラス型 'ADODB.InternalParameter' にキャストできません。COM コンポーネントを表す型のインターフェイスを COM コンポーネントを表さない型にキャストすることはできません。ただし、基になる COM コンポーネントがインターフェイスの IID の QueryInterface 呼び出しをサポートする場合は、インターフェイスにキャストすることができます。
↑↑↑↑↑ 例外内容 ↑↑↑↑↑

↓↓↓↓↓ 処理ロジック ↓↓↓↓↓
Dim objCon As New ADODB.Connection
Dim objCom As New ADODB.Command
Dim objPara As New ADODB.Parameter

Try
objCon.ConnectionString = _
"Provider=OraOLEDB.Oracle;" & _
"Data source=DSN_NAME;" & _
"User Id=USER_ID;" & _
"Password=PASSWD;" & _
"FetchSize=1000"

objCon.Open()

objCom.ActiveConnection = objCon
objCom.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc

'このappendでエラーが発生する objCom.Parameters.Append(objCom.CreateParameter("P1", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamInput, 4000, "ABCD"))
objCom.CommandText = "KS_PKG.ks_sample"
objCom.Execute()

objCon.Close()

Catch ex As Exception
MessageBox.Show(ex.Message)

End Try
↑↑↑↑↑ 処理ロジック ↑↑↑↑↑

【解決するために何をしたか】

コード内容の確認も含め、vb.net2003、vb.net2008のバージョンで同一コードを実施しましたが、問題なく正常に処理されストアドプロシージャの実行もされました
※2003、2008はPro版

2010バージョンがいけないのか、Express版の問題なのかは不明です。2010のPro版が手元にないので実施できていません。

既存システムとの絡みがあり、ADO.NETではなくADODBを利用しなくてはいけなく、知識不足のため解決策がみえない状況です。

ご教授頂けたら幸いです。

以上
> vb.net2010 express版を使用して、ADODBを使いオラクルへ接続を行っています。

  ADODB 使っている時点で、NG
  ADO.NET なのだが、Oracleなので、ODP.NET 使うべし。

  因みに、Oracle のバージョンは?

以上。
■No31188に返信(オショウさんの記事)
>>vb.net2010 express版を使用して、ADODBを使いオラクルへ接続を行っています。
>
>   ADODB 使っている時点で、NG
>   ADO.NET なのだが、Oracleなので、ODP.NET 使うべし。
>
>   因みに、Oracle のバージョンは?
>
> 以上。

すばやい回答、ありがとうございます。

オラクルのバージョンは11gになります。

ODP.NETの利用はごもっともなのですが、俗に言う客先都合と言うやつでして、保守性重視により関連既存システムと同じ手法で...との事。
と、言いながら、VB6.0ではなく開発環境だけは新しい物と言う...愚痴ですw

以上、よろしくお願いします
> オラクルのバージョンは11gになります。
>
> ODP.NETの利用はごもっともなのですが、俗に言う客先都合と言うやつでして、保守性重視により関連既存システムと同じ手法で...との事。
> と、言いながら、VB6.0ではなく開発環境だけは新しい物と言う...愚痴ですw

  私も現在、Oracle案件を抱えていて、同様の問題は理解して
  います。

  OracleクライアントのOCI を直接呼び出す方法なら簡単解決
  なんですがネ〜

  引数の受け渡しが少々厄介なので、C++ CLIでラッパーDLL
  作って、VB.NETとつないでます。

以上。参考まで
■No31187に返信(鈴木Mさんの記事)
> vb.net2010 express版を使用して、ADODBを使いオラクルへ接続を行っています。

ADODB のライブラリには、COM のタイプライブラリ(msado15.dll 等)から
自動生成される IA (Interop.ADODB.DLL 等)と、署名の施された
公式版となる PIA (Adodb.dll) とがあります。推奨されるのは後者です。

現在はおそらく後者をお使いであろうかと思いますが、両者では、
オブジェクト使用後の後始末(ReleaseComObject)の仕方が異なることに注意してください。
これは後者では、Fileds、Parameters、Properties コレクションなどといった
一部のオブジェクトが、マネージ化されているためです。
http://social.msdn.microsoft.com/Forums/ja/vbgeneralja/thread/a9ab2a55-6cf1-468a-9dc4-b0d99ff775eb


> 'このappendでエラーが発生する objCom.Parameters.Append(objCom.CreateParameter("P1", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamInput, 4000, "ABCD"))
objParams = objCom.Parameters
objParam = objCom.CreateParameter("P1", …)
objParams.Append(objParam)

のように、一度変数に受けるようにした方が良いでしょう。

その上で利用後の後始末として、各変数が COM オブジェクトかどうかを
Marshal.IsComObject で判定し、True を返してきた場合には、
Marshal.ReleaseComObject に渡して解放する必要があります。
http://support.microsoft.com/kb/321415/ja


Command.Parameters だけでなく、Recordset.Fields 等も同様です。
http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?print+200801/08010023.txt



> 2010バージョンがいけないのか、Express版の問題なのかは不明です。
参照設定\ADODB のプロパティを開き、「相互運用機能型の埋め込み」を
False にした場合、エラーが変化するかどうかを確認してみてください。
(Express で設定できるかは未確認です)

VB2010 からは、COM オブジェクトの型定義を別DLLとして用意するのではなく、
その型定義情報を EXE 内に内包する仕組みが追加されています。
具体的には、下記の「相互運用機能型の埋め込み」のあたりの事です。
http://msdn.microsoft.com/ja-jp/magazine/ee336123.aspx

より専門的な内容としてはこのあたり。
http://msdn.microsoft.com/ja-jp/library/vstudio/dd997297.aspx


先ほど書いた「一部のマネージ化されたオブジェクト」については、
相互運用機能型の埋め込みを行うと、うまく処理できない可能性があります。
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=10933&reno=10932&oya=10932&mode=msgview&page=0
(今回のエラーが、この件が原因であるかどうかは分かりませんが)


ちなみに、相互運用機能型の埋め込みを使っている場合、エディットコンティニューに
影響を与える可能性があるようです。蛇足までに。
http://ap.atmarkit.co.jp/bbs/core/fdotnet/27997


> ご教授頂けたら幸いです。
http://www.tt.rim.or.jp/~rudyard/torii009.html
http://blogs.wankuma.com/jeanne/archive/2005/11/24/19566.aspx
■No31190に返信(鈴木Mさんの記事)

> ODP.NETの利用はごもっともなのですが、俗に言う客先都合と言うやつでして、保守性重視により関連既存システムと同じ手法で...との事。
> と、言いながら、VB6.0ではなく開発環境だけは新しい物と言う...愚痴ですw
相性の悪いライブラリを使用し続けることは保守性が良いとは思えません。
コンバート時のテストをしっかり行わせてもらえばそれ以降の保守性は良くなるのではないでしょうか。
お世話になります。鈴木Mです。

>
>>2010バージョンがいけないのか、Express版の問題なのかは不明です。
> 参照設定\ADODB のプロパティを開き、「相互運用機能型の埋め込み」を
> False にした場合、エラーが変化するかどうかを確認してみてください。
> (Express で設定できるかは未確認です)
>

このプロパティ False にしてみたところ例外発生せず処理が実行できました。
今回の開発・運用環境はHDDクローンをベースとした限られた環境になる
のでこの機能は利用しない方向で行く事にします。

また、明示的な解放についてもご教示頂きたすかりました。
              ^^^^^^この件も結構うれしかったりします。

本当にありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板