DBNull与Null的区别
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是不等的。
DBNull与Null的区别的更多相关文章
- .NET和SQL Server中“空值”辨析 (DBNull与Null的区别)
对表进行插入操作,如datetime和int类型的两个字段,都允许为null,用“sqlcmd.Parameters.Add("@t12",tb12.Text)”参数绑定时.dat ...
- DBNull与Null
DBNull与Null的区别在于,DBNull代表该字段在数据库中根本不存在,Null代表该字段在数据库中没有值.
- C# DBNULL与NULL之间的区别【转】
null是.net中无效的对象引用.DBNull是一个类.DBNull.Value是它唯一的实例.它指数据库中数据为空(<NULL>)时,在.net中的值.null表示一个对象的指向无效, ...
- C#中的DBNull、Null、""和String.Empty
1.对DBNull的解释: 该类用于指示不存在某个已知值(通常在数据库应用程序中). 在数据库应用程序中,空对象是字段的有效值.该类区分空值(空对象)和未初始化值(DBNull.Va ...
- JavaScript中undefined与null的区别
通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会 ...
- string.empty和null的区别
关于String.Empty和Null的问题是这样的,这两个都是表示空字符串,其中有一个重点是string str1= String.Empty和 string str2=null 的区别,这样定义后 ...
- 类和对象 nil/Nil/NULL的区别
iOS-----类和对象,nil/Nil/NULL的区别 iOS中类和对象,nil/Nil/NULL的区别 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性 ...
- iOS-----类和对象,nil/Nil/NULL的区别
iOS中类和对象,nil/Nil/NULL的区别 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性)和动态属性(方法). 对象是类的一个实例,是一个具体的事物. ...
- iOS-nil,Nil,NULL的区别
一.简述 1.nil用来给对象赋值(Objective-C中的任何对象都属于id类型) 2.NULL则给任何指针赋值,NULL和nil不能互换 3.nil用于类指针赋值(在Objective-C中类是 ...
随机推荐
- Wamp修改端口
WAMP装好之后默认的端口是80,但是这个80端口呢,可以热门端口啊,迅雷,IIS都挺喜欢,在WIN7下本来还有1个进程也点80,让人伤脑筋啊,所以把它改掉,方法如下: 一.修改APACHE的监听端口 ...
- babel和postcss引起的一点儿思考
写es6,一般都会用到babel,它能把es6转为更好的es5,而es5可以直接在浏览器上运行.postcss是css界的babel,它可以把css转为更好的css,比如autoprefixer,让不 ...
- idea 开发插件。
作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com idea 开发插件. Intellij ID ...
- prufer序列计数的一些结论
\(prufer\)序列和完全图的生成树一一对应(考虑构造) 完全图的生成树个数为\(n^{n - 2}\) 满足第\(i\)个点的度数为\(d_i\)的生成树为\(\frac{n!}{\prod ( ...
- BZOJ.3720.Gty的妹子树(树分块)
题目链接 洛谷上惨遭爆零是为什么.. 另外这个树分块算法是假的. /* 插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort */ #include<cmath> #inclu ...
- Django-自定义增删改查组件的一些体会
1.路由系统 namespace,用于区分相同name的url,通过namespace为url添加一个前缀 反向生成URL的时候 reverse('namespace:name') {% url &q ...
- mongodb数组操作
1.查询课程中包含math,chinese的课程 db.getCollection('student').find( { course:{$all:['math','chinese']} } ).pr ...
- C++构造函数初始化列表与构造函数中的赋值的区别
C++类中成员变量的初始化有两种方式:构造函数初始化列表和构造函数体内赋值. 一.内部数据类型(char,int……指针等) class Animal { public: Animal(int wei ...
- 简单的proxy之TinyHTTPProxy.py
简单的proxy之TinyHTTPProxy.py 如果是在外企工作的话,可以访问美国的机器,这样就可以在美国的机器上为自己装个proxy,然后本地就可以很容易的使用proxy来上网了. TinyHT ...
- android:如何通过自定义工程模板让新建的工程都默认支持lambda表达式
首先参考这篇文章:自定义Android Studio工程模板,了解如何自定义模板 然后结合我们上一篇文章 android: 在android studio中使用retrolambda的步骤的要点, ...