将字符串转换为日期时间错误 [重复]

Posted

技术标签:

【中文标题】将字符串转换为日期时间错误 [重复]【英文标题】:Convert String to Datetime Error [duplicate] 【发布时间】:2016-09-22 14:14:38 【问题描述】:

我正在编写一个查询来轮询我们的一个设备并将状态报告回我们的 Solarwinds 服务器。这是一个半高级的 SQL 查询,我的结果是正确的,但我收到以下错误消息:

消息 242,第 16 级,状态 3,第 1 行 将 nvarchar 数据类型转换为 datetime 数据类型导致值超出范围。

我是 SQL 新手,所以我不确定如何解决。我的代码块如下:

SELECT tbl2.Load [Source], tbl3.Destination [Destination], tbl1.Status [Status], tbl4.Status [TimeStamp],
CONVERT(datetime, SUBSTRING (tbl4.Status,5,3) + ' ' + SUBSTRING(tbl4.Status,9,2) + ' , ' +  SUBSTRING(tbl4.Status,25,4) + ' ' + SUBSTRING(tbl4.Status,11,6)) AS DATE, 
DATEDIFF(HOUR,CONVERT(datetime, SUBSTRING (tbl4.status,5,3) + ' ' + SUBSTRING(tbl4.status,9,2) + ' , ' +  SUBSTRING(tbl4.status,25,4) + ' ' + SUBSTRING(tbl4.status,11,6)) , GETDATE()) AS Timediff
FROM Nodes n 

join (SELECT ca.nodeid, cs.Status [Load]
     FROM CustomPollerStatus cs 
JOIN CustomPollerAssignment ca ON (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID)
JOIN CustomPollerS cp ON ca.CustomPollerID=cp.CustomPollerID
     where cp.UniqueName='SnapMirrorSrc'
     ) tbl2 on n.Nodeid = 
tbl2.NodeID

join (select ca.nodeid, cs.Status [Destination]
    FROM CustomPollerStatus cs 
JOIN CustomPollerAssignment ca ON (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID)
JOIN CustomPollerS cp ON ca.CustomPollerID=cp.CustomPollerID
where cp.UniqueName='snapmirrordst'
) tbl3 on n.Nodeid = tbl3.NodeID

join (SELECT ca.nodeid, cs.Status
     FROM CustomPollerStatus cs 
JOIN CustomPollerAssignment ca ON (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID)
     JOIN CustomPollerS cp ON ca.CustomPollerID=cp.CustomPollerID
     WHERE cp.UniqueName='SnapMirrorState'
     ) tbl1 on n.Nodeid = tbl1.NodeID

join (select ca.nodeid, cs.Status
from CustomPollerStatus cs 
join CustomPollerAssignment ca ON (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID) 
JOIN customPollerS cp on ca.CustomPollerID=cp.CustomPollerID
WHERE cp.UniqueName='snapmirrorMirrorTimestamp'
) tbl4 on n.NodeID = tbl4.NodeID

where tbl1.Status like 'unk%' 

这是我的结果:

但是我收到此错误:消息 242,级别 16,状态 3,第 1 行 将 nvarchar 数据类型转换为 datetime 数据类型导致值超出范围。

所以我的结果是正确的,但我得到了这个错误。不确定是什么问题。任何帮助将不胜感激。

****--- 编辑 ---****

所以我稍微更改了我的代码,但是,现在在 DATE 列中我得到 1900-01-01 00:00:00.000

SELECT tbl2.Load [Source], tbl3.Destination [Destination], --tbl1.Status    [Status], 
tbl4.Status [TimeStamp],

CASE 
WHEN tbl4.status LIKE '[A-Z][A-Z][A-Z] %[1-9][1-9][1-9][1-9]' THEN 
CONVERT(datetime, SUBSTRING (tbl4.Status,5,3) + ' ' +    SUBSTRING(tbl4.Status,9,2) + ' , ' +  SUBSTRING(tbl4.Status,25,4) + ' ' +    SUBSTRING(tbl4.Status,11,6)) 
ELSE '' END AS [DATE], 

CASE 
WHEN tbl4.status LIKE '[A-Z][A-Z][A-Z] %[1-9][1-9][1-9][1-9]' THEN 
CAST (DATEDIFF(HOUR,CONVERT(datetime, SUBSTRING (tbl4.status,5,3) + ' ' +     SUBSTRING(tbl4.status,9,2) + ' , ' +  SUBSTRING(tbl4.status,25,4) + ' ' +     SUBSTRING(tbl4.status,11,6)) , GETDATE())AS bigint)
ELSE '' END AS 'Time Since Last Snap'
FROM Nodes n 

join (SELECT ca.nodeid, cs.Status [Load]
   FROM CustomPollerStatus cs 
  JOIN CustomPollerAssignment ca ON     (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID)
   JOIN CustomPollerS cp ON ca.CustomPollerID=cp.CustomPollerID
   where cp.UniqueName='SnapMirrorSrc'
   ) tbl2 on n.Nodeid = 
tbl2.NodeID

join (select ca.nodeid, cs.Status [Destination]
FROM CustomPollerStatus cs 
JOIN CustomPollerAssignment ca ON    (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID)
JOIN CustomPollerS cp ON ca.CustomPollerID=cp.CustomPollerID
where cp.UniqueName='snapmirrordst'
) tbl3 on n.Nodeid = tbl3.NodeID

join (select ca.nodeid, cs.Status
from CustomPollerStatus cs 
join CustomPollerAssignment ca ON     (cs.CustomPollerAssignmentID=ca.CustomPollerAssignmentID) 
JOIN customPollerS cp on ca.CustomPollerID=cp.CustomPollerID
WHERE cp.UniqueName='snapmirrorMirrorTimestamp'
) tbl4 on n.NodeID = tbl4.NodeID

【问题讨论】:

尝试在不转换为 DATETIME 的情况下执行 SELECT,看看是否有任何值不是有效日期。 另外,不要放置整个 SELECT,而是仅提供导致问题的那些部分(即与相关字段相关)。 您的图片显示状态列填充了值“未知”。这是 tbl4.Status 您正在尝试转换为日期时间吗? @openshac 不,未知数是不同的值。我试图转换 TimeStamp 列,因为它只是一个文本字符串,不是正确的日期时间,如果 Timediff 列大于 6,我想在该日期时间发出警报。 我应该说 - 我试图将字符串 TimeStamp 转换为日期时间并将其转储到格式正确的 DATE 列中 【参考方案1】:

检索年份部分可能出错:尝试使用 SUBSTRING(tbl4.status,22,4) 而不是 SUBSTRING(tbl4.status,25,4)

【讨论】:

【参考方案2】:

您的 tbl4.Status 列中似乎有一些无效数据。

为了识别无效数据暂时修改select和where子句语句为:

select tbl4.Status, *
...
where isdate(SUBSTRING (@status,5,3) 
        + ' ' + SUBSTRING(@status,9,2)
        + ' , ' +  SUBSTRING(@status,25,4) 
        + ' ' + SUBSTRING(@status,11,6)) = 0

编辑:

你的案例陈述

CASE
ELSE '' END AS [DATE]

当它落入 ELSE 部分时,将始终返回“1900-01-01 00:00:00.000”。这表明日期无效。

通过您在上面所做的编辑,只需将 tbl4.Status 添加到您的选择中,然后通过将其添加到您的 where 子句来识别无效行:

[DATE] = '1900-01-01 00:00:00.000'

这将识别不正确的状态行。

【讨论】:

嗨,看我上面编辑的评论

以上是关于将字符串转换为日期时间错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在c#中将字符串转换为日期[重复]

将JSON字符串转换为日期[重复]

将字符串'yyyy-mm-dd'转换为日期时间[重复]

nil 将字符串转换为日期 [重复]

将Javascript日期字符串转换为PHP日期[重复]

使用 C# 将字符串转换为 SqlServer 的日期时间 [重复]