1

我有一个表,其中有一DATETIME列名为dtInsertDate.

此列中的值为'2012-08-10 22:48:41.047'。我知道这个日期是 2012 年 8 月 10 日。

我想运行以下 SELECT 语句来检索这一行:

select *
from myTable
where dtinsertdate = '2012-08-10 22:48:41.047'

dateformat令人费解的是,如果我在选项为时运行此 SELECT mdy,它会找到该行。

如果我在选项dateformat为时在数据库的另一个副本上运行它dmySELECT则不会返回任何内容。

为什么是这样 ?

4

1 回答 1

5

原因是 dmy 导致您的字符串文字被解释为第一天 - 所以这是 10 月 8 日而不是 8 月 10 日。

解决方案是始终对日期文字使用明确的格式(或使用正确类型的参数,而不是首先处理从字符串进行翻译)。

WHERE dtinsertdate = '20120810 22:48:41.047';

正如您所发现的,日期中的这些破折号可以根据语言/日期格式设置对实际值进行不同的解释。

另一种选择是保留破折号但注入 T 而不是空格,例如:

WHERE dtinsertdate = '2012-08-10T22:48:41.047';

您的原件更具可读性,但只有在您固定语言和日期格式时才能保证工作(例如尝试使用SET LANGUAGE FRENCH;)。试试这个实验:

SET DATEFORMAT DMY;
DECLARE @d DATETIME = '2012-08-10 22:48:41.047'
SELECT MONTH(@d);
GO

SET LANGUAGE FRENCH;
DECLARE @d DATETIME = '2012-08-10 22:48:41.047'
SELECT MONTH(@d);
GO

SET DATEFORMAT MDY;
DECLARE @d DATETIME = '2012-08-10 22:48:41.047'
SELECT MONTH(@d);
GO

SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
DECLARE @d DATETIME = '2012-08-10 22:48:41.047'
SELECT MONTH(@d);
GO

有时结果是 8,有时结果是 10。现在用我上面建议的两种格式之一再试一次 - 结果总是 8。

我有很多有趣的细节值得在这里阅读:

但是对于您正在谈论的特定问题,始终,始终,始终使用以下格式之一作为日期/时间文字,我认为其他任何格式都不安全。

对于日期+时间:

YYYY-MM-DDTHH:MM:SS...
YYYYMMDD HH:MM:SS...

仅适用于日期:

YYYYMMDD
于 2012-08-11T14:24:04.217 回答