当 ADO.Net 运行查询时,什么决定了数据库的日期时间格式?



我有一个针对SQL Server数据库运行的简单测试查询。

SELECT IsDate('1' + '/' + '25' + '/' + '1993')

当我对数据库运行它时

set dateformat dmy

它正确返回 0

当我对数据库运行它时

set dateformat mdy

它正确返回 1

现在的问题是,当我从 .Net 中的SqlCommand对象运行此查询时,我没有得到预期的结果。

问题是我将线程的区域性和日期时间格式设置为 d/m/y。 即使我的线程以 d/m/y 格式运行并且我的数据库设置为 d/m/y,当从SqlCommand运行时,我仍然从我的查询中返回 1

示例代码:(注意:QuickQuery只是一个包装方法,它对我选择的数据库运行SqlCommand)

string query = $" SELECT IsDate('1' + '/' + '25' + '/' + '1993')";
var dt = QuickQuery(query);
return $"{dt.Rows[0][0]}" + $"            {new DateTime(1993, 1, 25)}";

此输出 = "1 25/01/1993 00:00:00">

当我的实际数据库和当前线程设置为 d/m/y 时,什么决定了SqlCommand是否在 m/d/y 上下文中运行?

我已经确认了我的数据库设置

DBCC USEROPTIONS

编辑 1:

只是一个简短的说明 - 我很欣赏关于以更好的方式做事的投入,这是有价值的。对于这种特殊情况,我无法遗憾地选择问题的上下文,我只是可以解决它。我为每个值月、日和年都有一个varchar列。它们可以是空值或文本。由此,我必须创建与实际datetime列的日期时间比较,并能够在服务器和正在运行的线程上使用任何日期时间格式!

本质上:完全避免问题。永远不要将日期称为字符串。使用定义和键入良好的参数。

本质上(切换到 Dapper 语法,因为它支持参数):

DateTime date = ...
var dt = connection.QuerySingle<DateTime>("select @date + 2", new {date});

其他数据也是如此 - 数字、小数分隔符和组分隔符也会遇到类似的问题,正确的方法不是学习 SQL Server 想要的格式:它不使用字符串,而是传递参数化值。这也会使意外陷入SQL注入漏洞变得更加困难。

最新更新