SQL SERVER 2008 R2中无效日期的日期与日期时间强制转换

SQL SERVER 2008 R2中无效日期的日期与日期时间强制转换,sql,date,datetime,sql-server-2008-r2,Sql,Date,Datetime,Sql Server 2008 R2,因此,虽然我认识到日期格式化等应该在表示层中完成,但我很想知道是否有人看到或认识到这种差异(如果愿意的话,请在家里试试)。我有点困惑,而且主要是好奇,首先是示例代码 更新:为了根据最初的回复进行澄清,我知道日期无效,或者更好的说法是“不安全”,因为我更普遍关注的特定字段来自用户输入。“也就是说,虽然我知道验证/格式设置不是SQL 2008的强项,但至少我很好奇DATETIME是否更宽容,我想知道是什么原因让我看到宽容程度如何。” 这将为我的服务器设置生成正确的结果:1901年1月20日12:00

因此,虽然我认识到日期格式化等应该在表示层中完成,但我很想知道是否有人看到或认识到这种差异(如果愿意的话,请在家里试试)。我有点困惑,而且主要是好奇,首先是示例代码

更新:为了根据最初的回复进行澄清,我知道日期无效,或者更好的说法是“不安全”,因为我更普遍关注的特定字段来自用户输入。“也就是说,虽然我知道验证/格式设置不是SQL 2008的强项,但至少我很好奇DATETIME是否更宽容,我想知道是什么原因让我看到宽容程度如何。”

这将为我的服务器设置生成正确的结果:1901年1月20日12:00AM

但是,如果倒数第二行更改为(将日期时间替换为日期):

Msg 241,16级,状态1,第8行 从字符串转换日期和/或时间时,转换失败

有什么解释吗?说得很清楚,如果我将@Value声明为日期或日期时间,甚至是NVARCHAR,这都无关紧要——同样的结果。错误消息似乎表明它在转换日期和/或时间时遇到了问题,为什么日期时间的行为会有所不同

谢谢,你能试一下吗

DECLARE @RawValue NVARCHAR(30), @Value DATE;
SET @RawValue = '01.20.1901' -- or '01/20/1901'

SET @Value = CAST(@RawValue AS DATE)
PRINT @Value

您的格式不正确

使用

而不是

SET @RawValue = '01/20.1901'

问题出在SQL Server引擎中,用于解析日期时间并将其强制转换为日期。值得一提的是,日期和日期时间是完全不同的数据类型。日期不仅仅是删除了时间的日期时间。例如,强制转换(“17520910”为日期)对历史爱好者来说,英格兰或她的殖民地没有这样的日子,日历从9月2日跳到9月14日。与日期时间不同,日期可以追溯到第一年,而不考虑日历系统

另一个重要的区别是缺少隐式类型转换来直接向日期添加天数。如果D是datetime,则D+3是三天之后的日期。如果D是date,则D+3产生错误


我假设,由于新的隐式转换代码是从零开始为DATE创建的,所以Microsoft只是让它变得更加挑剔。

我没有答案,但当然有一个解决办法:
set@Value=cast(cast(@RawValue as datetime)as DATE)
顺便说一句,我唯一的猜测是
datetime
类型在格式上比较新的
date
类型更宽容。由于您的输入中有混合标点符号,我实际上不希望任何一个都能正确解析它,但可能
datetime
只接受您抛出的任何数字,而不考虑符号。C将点挂在斜线上将导致成功转换为日期。这可能只是引擎的松散解释。但是即使是“正确”格式(例如
'01/20/1901'
),使用
mm/dd/yyyy
在任何层中表示日期的字符串都是一个糟糕的选择。请使用
SET LANGUAGE BRITISH;
SET DATEFORMAT DMY;
-会话设置您的代码可能无法控制任何方式。@JoeEnos+1对于这个想法,我应该更清楚。我知道这个老问题但要增加一个麻烦,isdate()函数实际上应该被称为isdatetime(),因为它检查某些东西是否将解析为dateTIME,而不是日期。我遇到了一个类似的问题,即“2/11/014”通过了isdate()检查,但未能转换为日期。
DECLARE @RawValue NVARCHAR(30), @Value DATE;
SET @RawValue = '01.20.1901' -- or '01/20/1901'

SET @Value = CAST(@RawValue AS DATE)
PRINT @Value
SET @RawValue = '01/20/1901'
SET @RawValue = '01.20.1901'
SET @RawValue = '01/20.1901'