在插入datetime时从字符串转换日期和/或时间时转换失败

Mar*_*ari 144 sql sql-server

我试图创建一个表如下,

create table table1(date1 datetime,date2 datetime);
Run Code Online (Sandbox Code Playgroud)

首先我尝试插入如下的值,

insert into table1 values('21-02-2012 6:10:00 PM','01-01-2001 12:00:00 AM');
Run Code Online (Sandbox Code Playgroud)

它说错了,

无法将varchar转换为datetime

然后我尝试下面的格式作为我们的stackoverflow建议的帖子之一,

insert into table1 values(convert(datetime,'21-02-2012 6:10:00 PM',5)
                          ,convert(datetime,'01-01-2001 12:00:00 AM',5));
Run Code Online (Sandbox Code Playgroud)

但我仍然得到错误说,

从字符串转换日期和/或时间时转换失败

有什么建议?

mar*_*c_s 140

SQL Server支持许多格式 - 请参阅CDN和CONVERT上MSDN联机丛书.大多数这些格式取决于您拥有的设置 - 因此,这些设置可能会有效 - 有时不会.

解决此问题的方法是使用SQL Server支持的(略微调整的)ISO-8601日期格式 - 此格式始终有效 - 无论您的SQL Server语言和日期格式设置如何.

ISO-8601格式由SQL Server支持有两种形式:

  • YYYYMMDD只为日期(没有时间部分); 请注意:没有破折号!,这非常重要!YYYY-MM-DD不是独立于你的SQL Server的日期格式设置,将适用于所有情况!

要么:

  • YYYY-MM-DDTHH:MM:SS对于日期和时间 - 请注意:此格式破折号(但可以省略),并且T在您的日期和时间部分之间固定为分隔符DATETIME.

这适用于SQL Server 2000及更高版本.

所以在你的具体案例中 - 使用这些字符串:

insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');
Run Code Online (Sandbox Code Playgroud)

你应该没问题(注意:你需要使用国际24小时格式而不是12小时AM/PM格式).

或者:如果您使用的是SQL Server 2008或更高版本,您也可以使用DATETIME2数据类型(而不是普通版DATETIME),您的当前INSERT工作将毫无问题!:-) DATETIME2是一个更好的,更不那么挑剔的转换 - 它是SQL Server 2008或更新的推荐日期/时间数据类型.

SELECT
   CAST('02-21-2012 6:10:00 PM' AS DATETIME2),     -- works just fine
   CAST('01-01-2012 12:00:00 AM' AS DATETIME2)   -- works just fine  
Run Code Online (Sandbox Code Playgroud)

不要问我为什么整个主题如此棘手而且有些混乱 - 这就是它的方式.但是使用这种YYYYMMDD格式,您可以适用于任何版本的SQL Server以及SQL Server中的任何语言和日期格式设置.

  • 我可以确认'YYYYMMDD'日期格式正常工作,在SQL Server 2014上尝试它,作为在WHERE子句中指定文字日期的方法.许多坦克到@marc_s (3认同)

Ash*_*ada 22

SQL服务器中的转换有时不会因为使用的日期或时间格式而失败,这仅仅是因为您试图存储系统无法接受的错误数据.

例:

Create Table MyTable (MyDate);

Insert Into MyTable(MyDate) Values ('2015-02-29');

SQL Server将抛出以下错误:

Conversion failed when converting date and/or time from character string.

出现此错误的原因很简单,就是在2015年(2015年)没有这样的日期(2月29日).

  • _“此错误的原因很简单,即年份(2015)中没有这样的日期(Feb-29)” __这正是我收到此错误的原因。该答案考虑了此错误的最常见原因,而其他答案则没有。 (2认同)
  • 我从 Excel 工作表导入数据,其中空值实际上在单元格中具有“NULL”。这在数据库表中设置为字符串“Null”,因此尝试将字符串“Null”转换为日期时间。应该清空 Excel 中的“NULL”单元格。我是个白痴 :/ (2认同)

Raj*_*Raj 13

简单的回答 - 5是意大利语"yy",105是意大利语"yyyy".因此:

SELECT convert(datetime,'21-02-12 6:10:00 PM',5)
Run Code Online (Sandbox Code Playgroud)

会正常工作,但是

SELECT convert(datetime,'21-02-12 6:10:00 PM',105)
Run Code Online (Sandbox Code Playgroud)

会给出错误.

同样,

SELECT convert(datetime,'21-02-2012 6:10:00 PM',5)
Run Code Online (Sandbox Code Playgroud)

会给出错误,在哪里

SELECT convert(datetime,'21-02-2012 6:10:00 PM',105)
Run Code Online (Sandbox Code Playgroud)

将工作.


Shn*_*ugo 8

尽可能避免文化特定的日期/时间文字.

有一些安全格式可以提供日期/时间作为文字:

所有的例子 2016-09-15 17:30:00

ODBC(我最喜欢的,因为它立即作为真实类型处理)

  • {ts'2016-09-15 17:30:00'} - 时间戳
  • {d'2016-09-15'} - 仅限日期
  • {t'17:30:00'} - 仅限时间

ISO8601(最适合各地)

  • '2016-09-15T17:30:00'- 请注意T中间!

不合时宜(很小的风险被误解为数字)

  • '20160915' - 仅限于纯粹的约会

请记住:无效的日期往往会出现奇怪的错误

  • 没有6月31日或2月30日......

奇怪的转换错误的另一个原因:执行顺序!

众所周知,SQL-Server按照可能没有预期的执行顺序执行操作.您的书面陈述看起来像转换是某些类型相关的操作发生之前完成的,但引擎决定 - 为什么还要 - 在稍后的步骤中进行转换.

这是一篇很好的文章用例子来解释:Rusano.com:"t-sql-functions-do-no-imply-a-certain-order-of-execution",这里是相关的问题.


Pro*_*Roy 6

只需更新日期格式即可

yyyy-MM-dd hh:MM:ss
Run Code Online (Sandbox Code Playgroud)

它解决了我的问题,它工作正常

  • 请阅读已经提供的其他答案。这种格式仅对您有效,因为您使用了会话“ DATEFORMAT”设置。通过运行SET DATEFORMAT MDY; SELECT CAST('2017-08-07 00:00:00'AS datetime)进行验证 SET DATEFORMAT DMY; SELECT CAST('2017-08-07 00:00:00'AS datetime);`。如果添加一个T分隔符(yyyy-MM-ddTHH:mm:ss),它将可以可靠地工作。 (2认同)

Abd*_*leh 6

这对我有用:

SELECT CONVERT(date, yourDate ,104)
Run Code Online (Sandbox Code Playgroud)


Hey*_*ude 6

当日期不存在时也会显示此错误(例如,日期'09-31-2021'不存在,因为 9 月的长度为 30 天)。


小智 5

最好的方法是这段代码

"select * from [table_1] where date between convert(date,'" + dateTimePicker1.Text + "',105) and convert(date,'" + dateTimePicker2.Text + "',105)"
Run Code Online (Sandbox Code Playgroud)