萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mssql數據庫 >> DBNull和Null的區別

DBNull和Null的區別

   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;

  }

  初學數據庫編程我們可能會有一些對"空值"的疑問,比如通過編程新建的一個表中所有數據皆顯示為,手動添加並刪除文字後又變成了空白;一個字符串類型的字段,明明沒有填值,卻不等於"";用ADO.NET從數據庫中取值,每遇到有的就出錯……這需要我們正確認識。NET和SQL Server中幾種不同的"空值".

  1、真正的空值,也就是"沒有輸入的值",可以出現在大多數類型的字段中(如果沒有別的約束條件),SQL server中表示為null,顯示為,手工在SQL server企業管理器中輸入的方法是按Ctrl+0.它在。NET中對應System.DBNull.Value.在T-SQL命令中,判斷一個值是不是空值,要用"is null"而不是"= null";處理空值有個ISNULL函數,它使用指定的值替換null.用ADO.NET從數據庫得到的空值無法自動轉化為空字符串或Nothing,須手動檢測:如果得到System.DBNull.Value,則賦給數據對象Nothing或其它自定義的有意義的值。

  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"不是沒有一樣

copyright © 萬盛學電腦網 all rights reserved