はじめまして、pinkと申します。
OS:Windows2000
VB:.net
VBを使いはじめて一ヶ月なのですが、DBの値の取得で躓いています。
以下のソースで
Dim cn As Object
Dim rs As Object
Dim sql As String
sql = "SELECT aaa, bbb, ccc FROM XXX"
'** ODBC 接続
cn = CreateObject("ADODB.Connection")
cn.Open("dsn=hoge;uid=sa;pwd=")
cn.CursorLocation = 3
'** レコードセットオープン
rs = cn.Execute(sql)
While Not rs.EOF
ListBox1.Items.Add(rs.Fields("aaa").Value & " " & rs.Fields("bbb").Value & _
'" " & rs.Fields("ccc").Value)
rs.MoveNext()
End While
'** レコードセットクローズ
rs.Close()
'** ODBC 接続解除
cn.Close()
Items.Addでエラーになります。
ちなみに、
rs("ccc").Valueもrs.Fields.Item("ccc").Value
もダメでした。
正しく値を取得するにはどうすればできるのでしょうか?
よろしくお願いします。
エラーの内容は?
Option Strict Onになってるなら文字型の連結できてないとか
rs("ccc").Value.ToString
Convert.ToString(rs("ccc").Value)
にしてみるとか
.netならDataReader使った方がいいと思うけど・・・
そのコードは、Option Strict Off モードでのコードですね。
個人的には、VB.NET では『ADO.NET』を使って接続すべきだとは思いますが、
どうしても従来の『ADO』を使わねばならないのであれば、COMの解放処理を
忘れずに行うようにしてください。たとえば、このような感じになります。
sql = "SELECT aaa, bbb, ccc FROM XXX"
cn.CursorLocation = 3 'adUseClient
cn.Open(接続文字列)
rs = cn.Execute(sql)
'後から Fields/Field を明示的に解放できるよう、別の変数に取っておく
Dim Fs As Object = RS.Fields
Dim F1 As Object = Fs("aaa")
Dim F2 As Object = Fs("bbb")
Dim F3 As Object = Fs("ccc")
Do Until rs.EOF
'一行で書いてしまうと、今回のエラーの原因を掴みにくいので、
'値を取得する部分を、複数行の処理に分割しています。
Dim Item As String
Item = F1.Value.ToString() & " "
Item &= F2.Value.ToString() & " "
Item &= F3.Value.ToString()
ListBox1.Items.Add(Item)
rs.MoveNext()
Loop
'以下はCOMクラスの解放処理。解放する順番やCloseを呼び出す位置に注意すること。
If System.Runtime.InteropServices.Marshal.IsComObject(F3) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(F3)
End If
If System.Runtime.InteropServices.Marshal.IsComObject(F2) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(F2)
End If
If System.Runtime.InteropServices.Marshal.IsComObject(F2) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(F2)
End If
If System.Runtime.InteropServices.Marshal.IsComObject(F1) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(F1)
End If
If System.Runtime.InteropServices.Marshal.IsComObject(Fs) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(Fs)
End If
rs.Close()
If System.Runtime.InteropServices.Marshal.IsComObject(rs) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs)
End If
If System.Runtime.InteropServices.Marshal.IsComObject(cn) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(cn)
End If
cn.Close()
なお、実際にはエラー発生時などに備えて、Try〜Catch〜Finally を使って
処理するべきなのですが、上記ではエラー対処を省略して書いています。
---- 以下、サポート技術情報より抜粋 ---
[高負荷下で ADO を .NET COM interop または Java で使用するとアクセス違反が発生する]
http://support.microsoft.com/kb/321415/ja
》 ActiveX Data Objects (ADO) を COM interop を介して使用するMicrosoft .NET プログラムや、
》 ADO を使用する Java プログラムで、ADO Connection オブジェクトの Close メソッドを
》 呼び出すと、アクセス違反が発生する場合があります。
(中略)
》 以下の 2 つのコーディング例を使用することで、この問題が発生する可能性を低く抑えることができます。
》
》* COM オブジェクトの使用後、明示的に COM オブジェクトへの参照を解放する。
》 →ReleaseComObject メソッドを使用してオブジェクトへの参照を解放することができる
》
》* ADO プライマリ相互運用アセンブリ (primary interop assembly) を使用する。
> If System.Runtime.InteropServices.Marshal.IsComObject(cn) Then
> System.Runtime.InteropServices.Marshal.ReleaseComObject(cn)
> End If
> cn.Close()
うっ。逆ですね。最後の部分は、
cn.Close()
If System.Runtime.InteropServices.Marshal.IsComObject(cn) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(cn)
End If
にしておいてください。m(_ _)m
お返事が、大変々遅くなり申し訳ありません。
pinkです。
みなさんのご意見を参考にさせて頂き、
結局、ADO.NETを使いました。(使えました。)
ありがとうございました。
解決のチェックを忘れていました!
ツイート | ![]() |