DBNull 類
表示不存在的值。無法繼承此類。
命名空間: System
程序集: mscorlib(在 mscorlib.dll 中)
DBNull 類表示一個不存在的值。例如,在數據庫的表中,某一行的某列中可能不包含任何數據。即,該列被視為根本不存在,而不只是沒有值。一個表示不存在的列的 DBNull 對象。此外,COM 互操作使用 DBNull 類來區分 VT_NULL 變量(指示不存在的值)和 VT_EMPTY 變量(指示未指定的值)。
DBNull 類型是一個單獨的類,這意味著只有一個 DBNull 對象存在。DBNull::.Value 成員表示唯一的 DBNull對象。DBNull::.Value 可用於將不存在的值顯式分配給數據庫字段,但大多數 ADO.NET 數據提供程序在字段沒有有效值時會自動分配 DBNull 值。您可以通過將從數據庫字段檢索到的值傳遞給 DBNull.Value.Equals 方法,確定該字段值是否為 DBNull 值。然而,有些語言和數據庫對象提供一些方法,可以更容易地確定數據庫字段值是否為 DBNull::.Value.這些方法包括 Visual Basic 的 IsDBNull 函數、Convert::.IsDBNull 方法、DataTableReader::.IsDBNull 方法和 IDataRecord::.IsDBNull 方法。
請勿將面向對象的編程語言中的 nullNothingnullptrnull 引用(在 Visual Basic 中為 Nothing) 概念與 DBNull對象混淆。在面向對象的編程語言中,nullNothingnullptrnull 引用(在 Visual Basic 中為 Nothing) 表示不存在對某個對象的引用。DBNull 則表示未初始化的變量或不存在的數據庫列。
備注
示例
下面的示例調用 DBNull.Value.Equals 方法,來確定聯系人數據庫中的數據庫字段是否具有有效值。如果具有有效值,字段值將被追加到在標簽中輸出的字符串中。
C# 中的用法
private void OutputLabels(DataTable dt)
{
string label;
// Iterate rows of table
foreach (DataRow row in dt.Rows)
{
int labelLen;
label = String.Empty;
label += AddFieldValue(label, row, "Title");
label += AddFieldValue(label, row, "FirstName");
label += AddFieldValue(label, row, "MiddleInitial");
label += AddFieldValue(label, row, "LastName");
label += AddFieldValue(label, row, "Suffix");
label += "/n";
label += AddFieldValue(label, row, "Address1");
label += AddFieldValue(label, row, "AptNo");
label += "/n";
labelLen = label.Length;
label += AddFieldValue(label, row, "Address2");
if (label.Length != labelLen)
label += "/n";
label += AddFieldValue(label, row, "City");
label += AddFieldValue(label, row, "State");
label += AddFieldValue(label, row, "Zip");
Console.WriteLine(label);
Console.WriteLine();
}
}
private string AddFieldValue(string label, DataRow row,
string fieldName)
{
if (! DBNull.Value.Equals(row[fieldName]))
return (string) row[fieldName] + " ";
else
return String.Empty;
}
初學數據庫編程我們可能會有一些對"空值"的疑問,比如通過編程新建的一個表中所有數據皆顯示為
1、真正的空值,也就是"沒有輸入的值",可以出現在大多數類型的字段中(如果沒有別的約束條件),SQL server中表示為null,顯示為
2、空字符串(零長度字符串),只出現在字符串類型(如nvarchar)的字段中,SQL server中表示為'',顯示為空白,手工在SQL server企業管理器中輸入時清空一個單元格即可。它在。NET中對應System.String.Empty,也就是我們常用的"".在T-SQL命令中處理空字符串和處理一般的字符串沒什麼區別。用ADO.NET從數據庫得到的空字符串也和一般的字符串沒什麼區別。
DBNull簡介
DBNull在DotNet是單獨的一個類型 System.DBNull .它只有一個值 DBNull.Value .DBNull 直接繼承 Object ,所以 DBNull 不是 string , 不是 int , 也不是 DateTime …
但是為什麼 DBNull 可以表示數據庫中的字符串,數字,或日期呢?原因是DotNet儲存這些數據的類(DataRow等)都是以 object 的形式來儲存數據的。對於 DataRow , 它的 row[column] 返回的值永遠不為 null , 要麼就是具體的為column 的類型的值 . 要麼就是 DBNull . 所以 row[column].ToString() 這個寫法永遠不會在ToString那裡發生NullReferenceException.
DBNull 實現了 IConvertible . 但是,除了 ToString 是正常的外,其他的ToXXX都會拋出不能轉換的錯誤。
在 IDbCommand(OleDbCommand,SqlCommand…) 的ExecuteScalar的返回值中,情況可以這樣分析:
select 1 這樣返回的object是 1 select null 這樣返回的是DBNull.Value select isnull(null,1) 返回的是 1 select top 0 id from table1 這樣返回的值是null select isnull(id,0) from table1 where 1=0 返回的值是null
這裡 ExecuteScalar 的規則就是,返回第一列,第一行的數據。如果第一列第一行不為空,那麼ExecuteScalar就直接對應的DotNet的值。如果有第一行,但是第一列為空,那麼返回的是 DBNull .如果一行都沒有,那麼ExecuteScalar就返回null
規則就是這樣的。這裡容易犯的一個錯誤是,把ExecuteScalar返回DBNull與null的情況混淆,例如:
string username=cmd.ExecuteScalar()。ToString();
除非你認為cmd執行後,肯定至少有一行數據,否則這裡就會出錯。
又或者 select id from usertable where username=@name 這樣的sql語句,如果找不到記錄,那麼ExecuteScalar則會返回null,所以千萬不要
int userid=Convert.ToInt32(cmd.ExecuteScalar());
或者你會這樣寫 SQL 語句:select isnull(id,0) from usertable where username=@name
但是 int userid=Convert.ToInt32(cmd.ExecuteScalar()); 依然會出錯,因為上面的語句不成立時,仍然是不返回任何行。
對於IDbDataParameter(OleDDbParameter,SqlParameter)的Value,如果為null,則代表該參數沒有指定,或者是代表DEFAULT.如果為DBNull.Value,則代表SQL中的NULL
所以,如果你要調用存儲過程,裡面有參數 @val nvarchar(20)="AABB" , 那麼cmd.Parameters["@val"].Value=null 代表使用這個默認的 "AABB" 而cmd.Parameters["@val"].Value=DBNull.Value 代表使用NULL來傳給 @val
你可以用Convert.IsDBNull來判斷一個值是否DBNull.注意Convert.IsDBNull(null)是false.
補充:DBNull指的是數據庫中的"null",而不是CLR中的"null".
如很多初學者以為下面是一樣的:
cmd.Parameters["@payment_type"].Value = "";
cmd.Parameters["@payment_type"].Value = System.DBNull.Value;
""表示的是空字符串,而System.DBNull.Value代表的是數據庫中的NULL,既沒有數據。就象老師說"0"不是沒有一樣