none
cmdSQL.ExecuteScalar 或 sdrDataTable.Read 傳回值的問題 RRS feed

  • 問題

  • 請教

    cmdSQL.ExecuteScalar 或 sdrDataTable.Read

    如果該資料表無資料,則會傳回 DBNull.Value 還是 Nothing ?

    因為看某些資料庫程式設計的書,範例如下面

            Dim sSQL = "SELECT MAX(" & MyIDFieldName & ") AS ID FROM " & MyTableName
            Dim cmdSQL As New SqlCommand
            Dim NewID As String
         
            cmdSQL.CommandText = sSQL
            cmdSQL.Connection = MyConnection

            MyConnection.Open()
            NewID = cmdSQL.ExecuteScalar
            MyConnection.Close()

            If NewID <> Nothing Then
                MyID = NewID
                FillData()
            End If

      實際測試時,當資料表無資料時,則傳回 DBNull 型別,
      也就是說程式執行到 NewID = cmdSQL.ExecuteScalar ,
      就會產生例外狀況,這是作者未考慮到的情形嗎?

     

     

    2010年2月8日 上午 07:03

解答

所有回覆

  • 資料庫的 NULL 值是 DBNull.Value,不是 Nothing。
    http://www.dotblogs.com.tw/regionbbs/archive/2008/10/09/5635.aspx


    初學不是問題,但用不正確的態度來問問題,那就是很大的問題。
    請不要藉新手之名行小白之實,否則只會讓更多無辜的新手得不到幫助而已。
    如果不知道什麼是小白,請參閱:何謂小白
    • 已標示為解答 roilee 2010年2月8日 上午 08:10
    2010年2月8日 上午 07:13
    版主
  •   實際測試時,當資料表無資料時,則傳回 DBNull 型別 

    無資料的時候:cmdSQL.ExecuteScalar 傳回null
    有資料但資料為null時:cmdSQL.ExecuteScalar 傳回DbNull.Value

    所以你這句話不正確,無資料時應傳回null
    2010年2月8日 上午 07:19
  • 那對 SqlDataReader 觀念也是一樣嗎?還有那為避免產生例外狀況,
    要如何對 cmdSQL.ExecuteScalar 判斷是否為 Null 值,因為如果
    用 DBNull.Value 是針對欄位資料為 Null 值的判斷。
    2010年2月8日 上午 07:29
  • 那對 SqlDataReader 觀念也是一樣嗎?還有那為避免產生例外狀況,
    要如何對 cmdSQL.ExecuteScalar 判斷是否為 Null 值,因為如果
    用 DBNull.Value 是針對欄位資料為 Null 值的判斷。

    1. 那對 SqlDataReader 觀念也是一樣嗎? 不太一樣
    無資料的時候:無 Row,可透過 HasRows 判斷
    http://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqldatareader.hasrows(VS.80).aspx

    有資料但資料為null時:DbNull.Value


    2. 為避免產生例外狀況,要如何對 cmdSQL.ExecuteScalar 判斷是否為 Null 值
    方法1 : IsDBNull 函式 : 傳回 Boolean 值,這個值表示運算式是否會評估為 System.DBNull 類別。
    http://msdn.microsoft.com/zh-tw/library/tckcces5.aspx

    方法2 : Try Catch

    我的Blog .NET菜鳥自救會
    2010年2月8日 上午 07:39
    版主
  • 最好的方式就是檢查其值是否為 null (nothing) 或是 DBNull.Value,不然只檢查其一很容易忽略掉另一個。
    初學不是問題,但用不正確的態度來問問題,那就是很大的問題。
    請不要藉新手之名行小白之實,否則只會讓更多無辜的新手得不到幫助而已。
    如果不知道什麼是小白,請參閱:何謂小白
    2010年2月8日 上午 07:50
    版主
  • 那麼為避免讀取資料因為 Null 產生的例外狀況,這樣寫是否就可以

             ' 針對資料表有資料時
             If Not IsDBNull(cmdSQL.ExecuteScalar) Then
                ' 針對資料欄位不是 Null 時
                If cmdSQL.ExecuteScalar IsNot DBNull.Value Then
                    ...
                End If
             End If

       ' 針對資料表有資料時
       if SqlDataReader.HasRows Then
          SqlDataReader.Read()

        ' 針對資料欄位不是 Null 時
          if SqlDataReader.GetValue(n) IsNot DBNull.Value Then
             ....
          End If
       End If

    2010年2月8日 上午 07:58
  • 如果不是很在意null或DbNull.Value的話
    可以不要判斷,直接用Convert.ToString()去包
    2010年2月8日 上午 08:02
  • 資訊「老」鳥,dot Net 菜鳥,感謝各位解了我困擾許久的問題。

    2010年2月8日 上午 08:10
  • 那麼為避免讀取資料因為 Null 產生的例外狀況,這樣寫是否就可以

             ' 針對資料表有資料時
             If Not IsDBNull(cmdSQL.ExecuteScalar) Then
                ' 針對資料欄位不是 Null 時
                If cmdSQL.ExecuteScalar IsNot DBNull.Value Then
                    ...
                End If
             End If

      


    這一段寫法自己實際測試發現應該更正如下,才不會出錯:
    If cmdSQL.ExecuteScalar IsNot Nothing Then
       ' 針對資料欄位不是 Null 時
        If cmdSQL.ExecuteScalar IsNot DBNull.Value Then
            ...
        End If
    End If

    因為當資料庫無資料 IsDBNull(cmdSQL.ExecuteScalar) 傳回  False
    2010年3月3日 上午 12:23
  • 即然 SELECT 裡使用了 MAX() 就不可能無資料,就算 Table 裡無資料也會傳回 DBNull,
    可以將查詢語法改成 
    Dim sSQL = "SELECT IsNull(MAX(" & MyIDFieldName & "),'') AS ID FROM " & MyTableName
    這樣就算無資料也會得到空字串,就不需要判斷了
    2010年3月4日 下午 04:39
  • 在 SQL 查詢語法使用 IsNull 函式,也是一種方法,就看自己方便了。謝謝!

    2010年3月9日 上午 12:15