ADOでSQL*Serverにデータを取得しにいってます。
データがNULL値の可能性があるのでISDBNULL関数を使用しているのですが、NULL値でもFALSEが返ってきます。
どこか間違えてますでしょうか?
dim cnn As New ADODB.Connection()
dim rs As New ADODB.Recordset()
dim str_sql as string
str_sql = "Provider=SQLOLEDB;Data Source=(local);Initial Catalog=labeler;User Id=sa;Password=;"
cnn.Open(mMYLABEL.str_sql)
str_sql = "select * from ProductCatM"
rs = cnn.Execute(str_sql)
msgbox(isdbnull(rs("ProductID")))がデータの内容にかかわらずfalseが返ってきます。
> dim cnn As New ADODB.Connection()
ADO ではなく、ADO.NET を使いましょう…。
Com Interop が発生するので、.NET から ADO を使うのは効率が悪いですよ。
解放処理のための System.Runtime.InteropServices.Marshal.ReleaseComObject の
呼び出しだって大変ですし。
> dim rs As New ADODB.Recordset()
ここで New しておく意味は無いですよね。
> str_sql = "Provider=SQLOLEDB;Data Source=(local);Initial Catalog=labeler;User Id=sa;Password=;"
> cnn.Open(mMYLABEL.str_sql)
ここでいう mMYLABEL とは何ですか? str_sql だけで良い気がしますが…。
> NULL値でもFALSEが返ってきます。
値そのものではなく、Field オブジェクトを渡しているからですよ。
IsDBNull(rs("ProductID")) ではなく、
IsDBNull(rs.Collect("ProductID")) とか、
IsDBNull(rs.Fields.Item("ProductID").Value) とか、
IsDBNull(rs.Fields("ProductID").Value) とか、
IsDBNull(rs.Fields!dt.Value) とかにしないと。
.NET掲示板への書き込みだけど、
MsgboxってことはVB6なんでしょうか。
> VB6なんでしょうか。
いや、.NET だと思いますよ。
VB6 だったら構文エラーになるでしょうし。
元ソースのコピー & ペーストでは無さそうなので、確証は持てませんが、
おそらくは(VB.NET 2003 ではなく)、VB.NET2002 か VB2005 じゃないですかね。
>> 解放処理のための System.Runtime.InteropServices.Marshal.ReleaseComObject の
>> 呼び出しだって大変ですし。
ちなみに…ActiveX 版(参照設定の COM タブにある方)を使っている場合と、
PIA 版(参照設定の .NET タブにある方)を使っている場合とで、解放すべき
オブジェクトが異なってくるので、注意してください。
Connection, Recordset, Command などのオブジェクトは COM オブジェクトであり、
参照設定に ActiveX 版 / PIA版のいずれを使っていても、上記 ReleaseComObject にて
解放せねばなりません。
一方、Properties, Property, Fields, Field, Parameters, Parameter などは、
COM 版では COM オブジェクトですが、PIA 版ではマネージオブジェクトなので、
PIA 版を使っている限り、これらのオブジェクトの解放作業が不要となります。
たとえば、先の Recordst の NULL チェックにしても、PIA 版では、
b = IsDBNull(rs.Fields("ProductID").Value) 'NULL確認
rs.Close() 'カーソル破棄
Marshal.ReleaseComObject(rs) 'COMオブジェクト解放
だけで済む解放作業が、COM 版を参照設定していた場合には、
fs = rs.Fields
f = fs("ProductID")
b = IsDBNull(f.Value) 'NULL確認
Marshal.ReleaseComObject(f)
Marshal.ReleaseComObject(fs)
rs.Close() 'カーソル破棄
Marshal.ReleaseComObject(rs)
という面倒な作業になります。
# そして(ADO ではなく)ADO.NET を使えば、そもそも
# Marshal.ReleaseComObject での解放作業自体が不要になります。
ありがとうございます。言語はVB2005です。
ADO.NETですが、調べてみました。
NULL値の判断もできているみたいですし、あってますでしょうか?
Dim cnn As New SqlConnection("Integrated Security=false;data source=(local);Initial Catalog=testcat;;User Id=test01;Password=test00;")
str_sql = "SELECT * from ProductM"
Dim myCommand As New SqlCommand(str_sql, cnn)
cnn.Open()
Dim rs As SqlDataReader = myCommand.ExecuteReader()
If rs.HasRows = False Then Exit Sub
Do While rs.Read
If IsDBNull(rs("ProductSize")) Then
MsgBox("false")
End If
Loop
rs.close
cnn.close
間違ってはないと思いますよ。
ADO.NETにはオーバロードもたくさんあるので勉強されてみると面白いですよ。
ちなみにExcecuteReaderは、クエリの結果の行数も返します。それで、
If rs.HasRows = False Then Exit Sub
は、別の表記もできますし、そもそも不要かと。
ツイート | ![]() |