在数据库应用程序开发中,由于字符串应用灵活和转换其他类型方便,所以经常把日期格式的字符串保存到数据表的日期字段中。由于设计规划的要求,当表示日期的字符串为空字符串时,要求把数据表中对应的日期字段值设置为null。但如果对日期字段的赋值处理不当,就会出现意想不到的情况。
例4.12 保存空值到数据表日期字段存在的陷阱(光盘位置:光盘\MR\Instance\4\12\ SaveNullToDataBase),该实例的详细说明如下。
本实例实现保存商品的销售记录。在窗体上添加3个文本框,分别用来输入商品名称、销售数量及销售日期,本实例运行后的窗体如图4.21所示。
本实例实现保存商品销售记录的方法如下:
在上面的代码中,对表示日期的字符串变量做了这样处理,若在表示“销售日期”文本框(textBox3)中未输入日期,则该字符串变量指向null,然后通过SQL语句将null保存到数据表中。运行本实例,在窗体中输入商品名称和销售数量,但不输入销售日期,然后单击窗体中的“保存”按钮保存输入的商品销售信息。但是当打开数据表后,却发现日期字段的值并不为null,如图4.22所示。
图4.21 商品销售登记
图4.22 数据库记录
从图4.22中看出,日期字段的值均为1900-01-01,这是不符合设计要求的,必须进行改正。
当不输入销售日期时,程序已经让字符串变量指向了null,但为什么数据库中保存的值不为空呢?通过查询Microsoft SQL Server的帮助文档获得了这样的信息,当设置datetime或smalldatetime值时,如果只指定时间,则日期默认为1900年1月1日。如果只指定日期,则时间默认为12:00 AM(午夜)。这说明Microsoft SQL Server把C#中传递过来的null当做datetime数据类型的默认值来处理。
既然Microsoft SQL Server把C#中的null当做datetime数据类型的默认值来处理,难道就真的没有办法来解决这个问题吗?幸运的是C#提供了一个特殊的类型来描述null,这个类型就是DBNull,并且该类型提供了一个静态只读字段Value,该字段用来表示空值。本实例就是利用DBNull.Value字段解决了这个问题,修改后的代码如下: