C#程序想要选择数据< = 23:59:59但最终选择00:00:00时间戳的数据

时间:2014-12-09 09:58:36

标签: c# sql-server

这是我的第一个问题,请原谅任何可能发生的错误:)

我制作了一个C#程序,它使用Datatables从SQL Server数据库收集数据,然后使用Interop将结果导出到Excel电子表格。 该计划本身运行良好,并按计划进行;但是,当我尝试选择Date列小于或等于2014-05-31 23:59:59的数据时,我发现了一些错误。

据说我试图将所有数据提供到2014年5月1日。

我的代码首先启动"开始日期"后面使用的SQL命令的参数如下:

var firstDay = new DateTime(today.Year, today.Month, 1); //2014-05-01 00:00:00`

基于firstDay,它会启动参数

的日期
var periodTo = firstDay.AddSeconds(-1);`

我调试并得到了我想要的时间:2014-04-30 23:59:59

为数据条件添加更多参数后,它会执行使用提供的参数运行查询的方法。

queryResult = medicore.GenerateRegister(ConfigurationManager.AppSettings["queryDir"], ConfigurationManager.AppSettings["queryName"]);`

periodTo参数将映射到SQL脚本中的@EDate变量。 @EDate被声明为Datetime@Edate在这里发挥作用:

Select columns
From tables
Where Voucher.Date <= @EDate

我认为,该脚本看起来像Where Voucher.Date <= '2014-04-30 23:59:59'

问题是,生成的Excel文件中的结果还包含来自'2014-05-01'的数据,这些数据不应该存在...至少基于我设置的标准。

C#和SQL Server之间是否发生了某种舍入?

谢谢!

1 个答案:

答案 0 :(得分:3)

原因可能是Voucher.DateSMALLDATETIME,因此您隐式将'2014-04-30 23:59:59'转换为SMALLDATETIME

SET DATEFORMAT MDY;
SELECT  CONVERT(SMALLDATETIME, '2014-04-30 23:59:59')

这给出了&#39; 2014-05-01&#39;。

为什么不使用Less than运算符,而不是小于或等于?

SET DATEFORMAT MDY;

SELECT  ...
WHERE   Voucher.Date < '2014-05-01';

NB我已经发表了DATEFORMAT,因为yyyy-MM-dd(尽管是ISO标准)对于SQL Server中的DATETIMESMALLDATETIME数据类型不是文化不变的,如果(像我一样)您所在的国家/地区的默认日期格式为DMY,那么SELECT CONVERT(SMALLDATETIME, '2014-04-30')会给您转换错误。 yyyyMMdd是这两种类型的唯一文化不变日期格式。

一篇优秀且非常相关的文章是Aaron Bertrand的Bad habits to kick : mis-handling date / range queries