`

DBNull.Value与Null的区别

    博客分类:
  • C#
 
阅读更多
Null是.net中无效的对象引用。
DBNull是一个类。DBNull.Value是它唯一的实例。它指数据库中数据为空(<NULL>)时,在.net中的值。

以下是我测试的一个例子。
例:表tbl_Student
id     name     address
1      jim      <NULL>

将上述表数据填充到.net 的名为dt的DataTable中。
dt.Rows[0]["address"]不等于null但是等于DBNull.Value.
可见null表示一个对象的指向无效,即该对象为空对象。
DBNull.Value表示一个对象在数据库中的值为空,或者说未初始化,DBNull.Value对象是指向有效的对象。

另外注:对上述dt,如果有如下代码:dt.Rows[0][100]。结果如何?
并非想象中的null。而是出现异常:索引超出数组界限。
对于普通的引用类型变量,如果指向对象为null,则会提示:未将对象引用设置到对象实例。但对于使用dt.Rows[i][j]取值,如果第i行存在但i行没有j列,则直接出现异常,不会返回一个指向null的dt.Rows[i][j]。
所以:使用(dt.Rows[0][100]!=null)判断没有意义。为避免0行的100列不存在。可以判断(dt.Rows[0].ItemArray.Length>100).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Null是.net中无效的对象引用。
DBNull是一个类。DBNull.Value是它唯一的实例。它指数据库中数据为空(<NULL>)时,在.net中的值。
null表示一个对象的指向无效,即该对象为空对象。
DBNull.Value表示一个对象在数据库中的值为空,或者说未初始化,DBNull.Value对象是指向有效的对象。
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就返回null。如果有第一行,但是第一列为空,那么返回的是 DBNull 。如果第一列第一行不为空,那么ExecuteScalar就直接对应的DotNet的值。

规则就是这样的。这里容易犯的一个错误是,把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,也就是说null跟DBNull.Value是不等的。

分享到:
评论

相关推荐

    asp.net中DBNull.Value,null,String.Empty区别浅析

    在ASP.NET开发中,了解`DBNull.Value`, `null`, 和 `String.Empty`的区别至关重要,因为它们在处理数据和字符串操作时有不同的含义和用途。以下是对这三个概念的详细解析: 1. **DBNull.Value**: DBNull.Value是...

    对象不能从 DBNull 转换为其他类型

    当从数据库检索的数据为NULL时,.NET Framework使用DBNull.Value来表示这种空值状态。本篇文章将深入探讨“对象不能从DBNull转换为其他类型”的错误及其解决方法。 #### 错误解析 此错误通常发生在尝试将DBNull....

    asp.net中对数据库表插入null空值的问题

    2. **正确的NULL值处理**:使用`System.DBNull.Value`来表示NULL值,并确保在条件判断中正确地使用它。 ```csharp if (string.IsNullOrEmpty(tb12.Text)) { sqlcmd.Parameters["@t12"].Value = System.DBNull....

    c#读取图像保存到数据库中(数据库保存图片)

    代码如下:注:MyTools.g_PhotoField为数据库表中的图象字段名称//将图片保存到数据库中 if(this.picPhoto.Image==null) { m_DataRow[MyTools.g_PhotoField]=DBNull.Value; } else { try { MemoryStream ms = ...

    完整SqlHelper类详细中文注释

    p.Value = DBNull.Value; } command.Parameters.Add(p); } } } } /// 将DataRow类型的列值分配到SqlParameter参数数组. private static void AssignParameterValues(SqlParameter[] commandParameters, ...

    微软原版SQLHelper源码

    - 如果参数值为`null`,则将其设置为`DBNull.Value`,这有助于防止数据库端使用默认值。 2. **AssignParameterValues 方法** - **功能**:此方法用于将数据行的列值分配给`SqlParameter`数组中的参数。 - **...

    asp.net中Null在从数据库读取的时候的一点点小技巧

    第一种是直接与DBNull.Value进行比较,即if(dr["Name"] == DBNull.Value)。第二种是使用Convert.IsDBNull方法进行判断,即if(Convert.IsDBNull(dr["Name"]))。两种方式在逻辑上是等价的,都是正确的处理方式。作者在...

    CMS.DBUtility.dll

    if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { cmdresult = 0; } else { cmdresult = int.Parse(obj.ToString()); } if (cmdresult == 0) { return false; } else ...

    ASP.net开发出用函数

    在处理数据库结果时,`DBNull.Value`代表数据库中的NULL值。在尝试访问这些值之前进行检查非常重要,以防止运行时异常。如果字段值为NULL,`Eval("timeFromDB")`将返回`DBNull.Value`,所以这里用条件判断避免了...

    C#中SQL参数传入空值报错解决方案

    在C#中使用SQL参数传入空值时,会遇到报错的问题,这是因为C#中的null与SQL中的NULL是不一样的,SQL中的NULL用C#表示出来就是DBNull.Value。SQL参数不能接受C#的null值,传入null就会报错。下面我们来看一个例子: ...

    WPF中DataGrid的空白行使用方法

    return value == null || value is DBNull; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } ``` 通过...

    C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

     //假设字段为name, dt已经保存了数据dt.rows[0][“name”] == System.DBNull.Value; //判断第一行数据的name字段是否为空 2 通过IsNull判断 代码如下:DataTable dt; //假设字段为name, dt已经保存了数据dt.rows...

    SQLDBUnity

    if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { cmdResult = 0; } else { cmdResult = int.Parse(obj.ToString()); } if (cmdResult == 0) { return false; } else ...

    一个非常丰富的dbhelper类

    if (Object.Equals(obj, null) || Object.Equals(obj, System.DBNull.Value)) { return 1; } else { return int.Parse(obj.ToString()); } } ``` 通过构造SQL语句来获取指定字段的最大值,并在此基础上加一...

    sqlhelper类

    param.Value = DBNull.Value; // 添加参数到命令 command.Parameters.Add(param); } } ``` 2. **执行 SQL 语句**: `SQLHelper` 类提供了执行 SQL 语句的方法,包括查询、插入、更新和删除等操作。这些方法...

    c#往sqlserver2000数据库中插入时间型数据的空值

    然后,我们添加了一个`SqlParameter`,名为`@DateTimeValue`,类型设置为`SqlDbType.DateTime`,并将其值设置为`DBNull.Value`,这代表SQL中的`NULL`。最后,我们执行`ExecuteNonQuery()`来执行命令,从而将空值插入...

    将datatable里的数据导出DBF文件

    - 检查每列数据是否为`null`,如果为`null`则用`DBNull.Value`替换,这是因为DBF文件不支持直接存储`null`值。 - 代码示例: ```csharp for (int i = 0; i &lt; dt.Rows.Count; i++) { DataRow dr = dt1.NewRow()...

Global site tag (gtag.js) - Google Analytics