原因是 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