Sql server 将varchar数据类型转换为datetime数据类型导致值超出范围:仅限闰年日

Sql server 将varchar数据类型转换为datetime数据类型导致值超出范围:仅限闰年日,sql-server,datetime,leap-year,Sql Server,Datetime,Leap Year,在使用convert函数将getdate格式化为varchar8之后,我试图将date插入datetime列。我看到它在大部分情况下都能工作,但顺便提一下,当日期是闰日2月29日时,它会由于varchar到datetime错误的转换而失败 我将varchar8改为varchar9,最终解决了问题。知道2月29日在SQL server中的存储是否不同吗 CREATE TABLE [dbo].[temp_insert] ( [TimeStamp] [datetime] NULL, ) ON [PRI

在使用convert函数将getdate格式化为varchar8之后,我试图将date插入datetime列。我看到它在大部分情况下都能工作,但顺便提一下,当日期是闰日2月29日时,它会由于varchar到datetime错误的转换而失败

我将varchar8改为varchar9,最终解决了问题。知道2月29日在SQL server中的存储是否不同吗

CREATE TABLE [dbo].[temp_insert]
(
[TimeStamp] [datetime] NULL,
) ON [PRIMARY]

GO

insert into temp_insert values(convert(varchar(8),(getdate()+1),113))--*inserts 1st march 2020*

GO

insert into temp_insert values(convert(varchar(8),(getdate()),113))--*fails with conversion error*

GO

insert into temp_insert values(convert(varchar(9),(getdate()),113))--*giving 9 bytes in varchar, inserts 29th Feb without issues.*


GO

select * from temp_insert--*shows 2 rows including 29th feb leap day*

GO
如果你自己拿一个失败的插件,把它分成几个部分,问题就显而易见了


它失败是因为convertvarchar8,getdate,113返回varchar'29 Feb 2'。如果将值'28 Feb 2'转换为日期时间,则得到值2002-02-28 00:00:00.000;因此,“2月29日2”将是2002年2月29日。2002年不是闰年,因此转换失败。

这不是方法。您的表已经有一个datetime字段,因此不需要对诸如getdate之类的值使用convert,因为它们已经是datetime类型

只需将这些值存储为datetime,然后使用以您想要的方式呈现日期/时间


使用例如DATEADDday,1,getdate。请注意,使用here:TIMESTAMP是需要避免的。

在插入到datetime列时,为什么要将GETDATE转换为varchar。即使是这样,为什么是dd-mon-yyyy-hh:mi:ss:mmm格式而不是ISO格式yyyyMMdd?GETDATE返回datetime数据类型,那么它有什么问题吗?如果运行SELECT convertvarchar8,GETDATE,113,您也会看到问题。“2月29日”代表的是什么日期?@larnu:谢谢你的关注。我并不是说我发布的是正确的编码方式,但我想理解的是为什么2月29日需要在datetime列中插入一个额外的字节。我只是在和我的一个开发人员一起工作时偶然发现了这个问题,他向我寻求帮助。如果您运行我发布的代码段,您将看到它只适用于第一次和最后一次插入,而不适用于中间一次插入。您有自己的解释。简而言之,阅读转换文档,了解使用的样式,正确计算字符数,并且永远不要使用2位数的年份。更重要的是,学会调试自己的代码。除了让代码正常工作之外,这里还有很多可以改进的地方。