zoukankan      html  css  js  c++  java
  • [C#.net]将null值插入SQL Server的Datetime

    之前处理SQL Server可以为空时间字段总是设置时间的最小值和最大值,今天才发现也可以把null用C#的代码插入到sql内

    使用可空的值类型,代码如下

            public DateTime? ServiceDeadline { get; set; }
            public string CreateName { get; set; }
            public DateTime CreateTime { get; set; }
            public string UpdateName { get; set; }
            public DateTime? UpdateTime { get; set; }
                        if(txtServiceDeadline.Text.Trim().Length ==0)
                        {
                            di.ServiceDeadline=null;
                        }
                        else
                        {
                            di.ServiceDeadline = Convert.ToDateTime(txtServiceDeadline.Text.Trim().ToString(), dtFormat);
                        }
                        di.CreateName = userInfo.ChName;
                        di.CreateTime = DateTime.Now;
                        di.UpdateName = null;
                        di.UpdateTime = null;
                   new SqlParameter("@ServiceDeadline", SqlDbType.Date) { Value = di.ServiceDeadline==null?DBNull.Value:(object)di.ServiceDeadline },
                   new SqlParameter("@CreateName",SqlDbType.NVarChar,10){Value=di.CreateName},
                   new SqlParameter("@CreateTime",SqlDbType.DateTime){Value=di.CreateTime},
                   new SqlParameter("@UpdateName",SqlDbType.NVarChar,10){Value=di.UpdateName==null?DBNull.Value:(object)di.UpdateName},
                   new SqlParameter("@UpdateTime",SqlDbType.DateTime){Value=di.UpdateTime==null?DBNull.Value:(object)di.UpdateTime}

    还可以使用更简单的写法

    new SqlParameter("@UpdateTime",SqlDbType.DateTime){Value=(object)di.UpdateTime ?? DBNull.Value}

    总之参数值为NULL,输入数据库时要变成DbNull.Value

    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)="C" , 
    
    那么cmd.Parameters["@val"].Value=null 代表使用这个默认的 "C"
    
    而cmd.Parameters["@val"].Value=DBNull.Value 代表使用NULL来传给 @val
    
    你可以用Convert.IsDBNull来判断一个值是否DBNull。注意Convert.IsDBNull(null)是false,也就是说null跟DBNull.Value是不等的。

    C#中的?    ?:   ??的含义

    1. 可空类型修饰符(?):
    引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。
    例如:string str=null; 是正确的,int i=null; 编译器就会报错。
    为了使值类型也可为空,就可以使用可空类型,即用可空类型修饰符"?"来表示,表现形式为"T?"
    例如:int? 表示可空的整形,DateTime? 表示可为空的时间。
    T? 其实是System.Nullable(泛型结构)的缩写形式,也就意味着当你用到T?时编译器编译 时会把T?编译成System.Nullable的形式。
    例如:int?,编译后便是System.Nullable的形式。

    2. 三元(运算符)表达式(?:):
    例如:x?y:z 表示如果表达式x为true,则返回y;如果x为false,则返回z,是省略if{}else{}的简单形式。

    3. 空合并运算符(??):
    用于定义可空类型和引用类型的默认值。如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。
    例如:a??b 当a为null时则返回b,a不为null时则返回a本身。
    空合并运算符为右结合运算符,即操作时从右向左进行组合的。如,“a??b??c”的形式按“a??(b??c)”计算。
  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/masonlu/p/10134629.html
Copyright © 2011-2022 走看看