ISDBNULL関数で戻り値がFALSEになります。


杏子  2007-06-15 09:29:39  No: 143661

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が返ってきます。


魔界の仮面弁士  2007-06-15 12:04:45  No: 143662

> 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) とかにしないと。


KG  2007-06-15 18:03:11  No: 143663

.NET掲示板への書き込みだけど、
MsgboxってことはVB6なんでしょうか。


魔界の仮面弁士  2007-06-15 18:59:28  No: 143664

> 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 での解放作業自体が不要になります。


はなこ  2007-06-16 07:25:46  No: 143665

ありがとうございます。言語は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


A24  2007-06-23 21:30:35  No: 143666

間違ってはないと思いますよ。
ADO.NETにはオーバロードもたくさんあるので勉強されてみると面白いですよ。
ちなみにExcecuteReaderは、クエリの結果の行数も返します。それで、
If rs.HasRows = False Then Exit Sub
は、別の表記もできますし、そもそも不要かと。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加