【发布时间】:2019-07-02 22:44:05
【问题描述】:
我有一个性能监视器实例,将数据保存到 MS SQL 服务器数据库上的表中。性能数据保存到名为 CounterData 的表中。该表有一个 char(24) 字段 (counterdatetime) 用于存储数据的日期/时间。我试图将该字段视为日期时间数据,但我不断收到“从字符串转换日期和/或时间时转换失败。”
以下是来自 counterdatetime 的数据示例:2019-07-02 09:19:46.300
我尝试了 CAST 和 CONVERT 的不同变体,以允许我将这些数据作为日期时间处理。例如:
SELECT CAST(counterdatetime as datetime) from CounterData
SELECT CAST(counterdatetime as datetime2) from CounterData
SELECT CONVERT(datetime,counterdatetime,101) from CounterData
每个都给我“转换失败......”错误。我想也许失败是由一条记录中的虚假值触发的,所以我尝试使用指定一个好值的 WHERE 表达式来限制转换。我还尝试了转换值本身,如下所示:
SELECT CAST('2019-07-02 09:19:46.300' as datetime)
在这种情况下,CAST 有效。
为什么当我从表格中选择值时它不起作用?
更新
@Jeroen Mostert 在评论中提供了答案,我将其作为答案发布。
【问题讨论】:
-
"
The table has a char(24) field... I'm trying to treat that field as a datetime data" 不要那样做!如果您有 DateTime 值,请使用 DateTime 系列中的类型存储它们! -
我不相信
'2019-07-02 09:19:46.300'是导致您的查询崩溃的实际值。你确定吗? -
@JoelCoehoorn 使用 char(24) 不是我的选择。这就是性能监视器创建表的方式。
-
呃-哦,意大利面条-O。那是一个不属于那里的
NUL字符。这些非常糟糕,因为REPLACE默认情况下不知道如何处理它们。试试CONVERT(DATETIME, REPLACE(CounterDateTime COLLATE Latin1_General_BIN2, CHAR(0), ''))。 (SUBSTRING(CounterDateTime, 1, 23)在这种情况下也应该可以工作,因为我们可以预期NUL总是在最后。) -
一次性转换所有内容(因为一遍又一遍会很烦人):
UPDATE CounterData SET CounterDateTime = SUBSTRING(CounterDateTime, 1, 23); ALTER TABLE CounterData ALTER COLUMN CounterDateTime DATETIME应该负责打字。或INSERT另一个表中的内容,其中包含正确键入的列。如果您需要更灵活的永久设置,应该可以让 perfmon 使用INSTEAD OF触发器将其数据插入到视图中,该触发器将在数据有机会变得烦人之前转换数据。
标签: sql-server tsql