仅在更新期间从字符串转换日期和/或时间时转换失败
Posted
技术标签:
【中文标题】仅在更新期间从字符串转换日期和/或时间时转换失败【英文标题】:Conversion failed when converting date and/or time from character string during update only 【发布时间】:2018-12-13 20:56:15 【问题描述】:我一直在寻找解决方案很长一段时间,但似乎无法制定一个带回解决方案的查询,所以作为最后的手段,我在这里发布了。 我有一个带有 varchar 列的 SQL Server 表,其中的日期和时间以这种格式存储
"1/1/2013 11:38:31 PM Some other text"
我需要将此数据的日期和时间部分存储在 datetime 数据类型的另一列中。所以我创建了一个名为 DateTimeLog 的新列,类型为 datetime。
然后我用左键切掉多余的文本并转换以将值更改为日期时间格式并得到我期望的结果。
select CONVERT(DATETIME,(rtrim(left(olddate, 21)))) from mytable
results:
"2013-01-01 23:38:31.000"
到目前为止,一切都很好。这是我所期望的。当我尝试使用此 CONVERT 语句的结果更新我的新日期时间列时,我的麻烦就开始了。
update mytable
SET DateTimeLog = CONVERT(DATETIME,(rtrim(left(olddate, 21)))) from mytable
我收到臭名昭著的“从字符串转换日期和/或时间时转换失败”错误消息。
Conversion failed when converting date and/or time from character string.
我也尝试过使用演员表
update mytable
SET DateTimeLog = (cast(CONVERT(DATETIME,(rtrim(left(oldtable, 21)))) as datetime)) from mytable
错误仍然存在。尽我所能告诉转换工作正常,因为我可以从一个选择中看到结果集,但是到目前为止,将结果放入一个新列中让我望而却步。 谢谢,
【问题讨论】:
【参考方案1】:您的字符串不会始终为 21 个字符长。您的示例数据显示单个字符的月份和单个字符的日期。如果是 12/13/2018
呢?
也就是说,您需要一种更强大的方法来隔离该时间戳。我使用PATINDEX
来捕获时间组件中最后一个冒号的位置,其中有几个正则表达式来解释数字和 AM/PM 的事情。然后我添加了 6 以到达感兴趣的字符串的末尾。
这似乎有效:
DECLARE @t TABLE (olddate VARCHAR(100));
INSERT @t
(
olddate
)
VALUES
('12/13/2018 11:38:31 PM Some other text')
,('1/1/2018 11:38:31 PM Some other text');
SELECT CAST(LEFT(olddate,PATINDEX('%:[0-9][0-9] [AP]M%', olddate)+6) AS DATETIME)
FROM @t;
结果:
+-------------------------+
| 2018-12-13 23:38:31.000 |
| 2018-01-01 23:38:31.000 |
+-------------------------+
Rextester:https://rextester.com/BBPO51381(虽然输出的日期格式有点奇怪)。
【讨论】:
我只会提出一个建议...考虑到字符串转换的风险,请使用 try_cast() 或 try_convert()。 +1 ....哎呀。没看到 2008 是的。更高版本有很多更好的选择。 谢谢,我会试一试并报告。我认为 21 个字符覆盖了我的两位数日期,但我会验证。当我查看 SSMS 中的结果集时,输出测试正确无误,只有当我尝试获取转换后的值并更新表时才会发生故障。 您可能会丢失一个偶然的“M”,它会在末尾用静态值拾取杂散文本的第一个字符。希望对你有帮助! 埃里克,我想你在做点什么。在出现转换错误之前,我最多可以选择 13700 行。我的问题出在行数之外。我相信,试图找到它会很困难。以上是关于仅在更新期间从字符串转换日期和/或时间时转换失败的主要内容,如果未能解决你的问题,请参考以下文章
转换输入时间时从字符串转换日期和/或时间时转换失败 | SQL, SQLSRV