SQL Server:从字符串超过12pm的字符转换日期和/或时间时,转换失败
在过去的几天里,我的代码一直有效,但今天它出现了以下错误: 从字符串转换日期和/或时间时转换失败 这是我的密码:SQL Server:从字符串超过12pm的字符转换日期和/或时间时,转换失败,sql,sql-server,casting,type-conversion,Sql,Sql Server,Casting,Type Conversion,在过去的几天里,我的代码一直有效,但今天它出现了以下错误: 从字符串转换日期和/或时间时转换失败 这是我的密码: DECLARE @run_time INT DECLARE @run_duration INT SET @run_time = '120609' SET @run_duration = '2600' SELECT h.step_id, CAST(j.[name] AS VARCHAR) as JobName, h.step_name, CAST(
DECLARE @run_time INT
DECLARE @run_duration INT
SET @run_time = '120609'
SET @run_duration = '2600'
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
CAST(REPLACE(LEFT(CAST(case
when len(@run_time) = 1 then '00:00:0' + cast(@run_time as varchar)
when len(@run_time) = 2 then '00:00:' + cast(@run_time as varchar)
when len(@run_time) = 3 then '00:0' + cast(left(@run_time,1) as varchar) + ':' + cast(right(@run_time,2) as varchar)
when len(@run_time) = 4 then '00:' + cast(left(@run_time,2) as varchar) + ':' + cast(right(@run_time,2) as varchar)
when len(@run_time) = 5 then '0' + cast(left(@run_time,1) as varchar) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 2, 2) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 4,2)
when len(@run_time) = 6 then cast(left(@run_time,2) as varchar) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 4,2)
END AS TIME), 8), ':', '') AS INT) StartTime
我发现唯一出现错误的时间是运行时间超过120000(中午12点),因此我以前从未注意到它,因为代理作业在凌晨3点运行。这不应该是一个问题,在未来,但只是以防万一,我想修复这个问题。我在任何地方都找不到与我的代码类似的示例。不幸的是,像这样投射结果是我在SSRS中获得图形的唯一方法。(INT>VARCHAR>TIME>INT)
编辑-下面是我的代码的一个更好的示例,使用了其中一个建议的答案:
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
CAST(stuff(stuff(right('0000000' + h.run_time, 6), 5, 0, ':'), 3, 0, ':') as time)
FROM
msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
谢谢,如果您试图从HHMMSS格式的字符串计算开始时间,那么此方法对我来说似乎简单得多:
select cast(stuff(stuff(right('0000000' + str, 6), 5, 0, ':'), 3, 0, ':') as time)
from (values ('120609'), ('0'), ('1001')) v(str)
在您的例子中,问题是您试图转换的字符串:“12:20:60” 与时间类型的对话失败
DECLARE @run_time INT
DECLARE @run_duration INT
SET @run_time = '120609'
SET @run_duration = '2600'
SELECT
-- h.step_id,
--CAST(j.[name] AS VARCHAR) as JobName,
-- h.step_name,
--CAST(REPLACE(LEFT(CAST(
case
when len(@run_time) = 1 then '00:00:0' + cast(@run_time as varchar)
when len(@run_time) = 2 then '00:00:' + cast(@run_time as varchar)
when len(@run_time) = 3 then '00:0' + cast(left(@run_time,1) as varchar) + ':' + cast(right(@run_time,2) as varchar)
when len(@run_time) = 4 then '00:' + cast(left(@run_time,2) as varchar) + ':' + cast(right(@run_time,2) as varchar)
when len(@run_time) = 5 then '0' + cast(left(@run_time,1) as varchar) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 4,2)
when len(@run_time) = 6 then cast(left(@run_time,2) as varchar) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 2,2) + ':' + SUBSTRING(CAST(@run_time AS VARCHAR), 4,2)
END ,
SUBSTRING(CAST(@run_time AS VARCHAR), 4,2)
--AS TIME)
--,8), ':', '') AS INT) StartTime
你查过了吗?
最好的解决方案应该是Gordon提出的解决方案这对我很有效:
SELECT
h.step_id,
CAST(j.[name] AS VARCHAR) as JobName,
h.step_name,
-- CAST(stuff(stuff(right('0000000' + h.run_time, 6), 5, 0, ':'), 3, 0, ':') as time)
(h.run_time / 1000000) % 100 as hour,
(h.run_time / 10000) % 100 as minute,
(h.run_time / 100) % 100 as second,
(h.run_time % 100) * 10 as millisecond,
dateadd(hour, (h.run_time / 1000000) % 100, dateadd(minute, (h.run_time / 10000) % 100, dateadd(second, (h.run_time / 100) % 100, dateadd(millisecond, (h.run_time % 100) * 10, cast('00:00:00' as time(2))))))
FROM
msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
顺便说一句,演员阵容也会让我出错
如果您不想使用select语句:
DECLARE @run_time INT
DECLARE @time_result TIME
SET @run_time = '120609'
SET @time_result = dateadd(hour, (@run_time / 1000000) % 100, dateadd(minute, (@run_time / 10000) % 100, dateadd(second, (@run_time / 100) % 100, dateadd(millisecond, (@run_time % 100) * 10, cast('00:00:00' as time(2))))))
select @time_result
你能解释一下代码应该做什么吗?输入和结果的示例是什么?代码查看msdb.dbo.sysjobs和msdb.dbo.sysjobhistory,并获取作业的开始时间。这是一个INT,然后我将强制转换为varchar,然后时间,在删除冒号后返回到INT。因此,我可以将其绘制在带有开始时间和作业持续时间的图表上,以确保etl计划按顺序运行。不幸的是,由于SSRS报告的权限,我无法立即使用msdb.dbo.agent_jobtime。您正在将
@run_time
和@run_duration
声明为INT
,然后将它们设置为隐式字符串数据类型。您是否希望最终返回到datetime
数据类型。是的,我在这个问题示例中声明了它们,因为从表中我得到了它们,它们是一个INT。我将用一个更好的代码示例编辑我的问题。谢谢,如果我可以使用它,它肯定会大大缩短我的代码。我已经在我的原始问题中添加了一个示例,但我仍然得到相同的错误。@Jas。然后,您似乎有一个字符串作为时间格式无效,或者超过了'250000'
。如果你想避免这个问题,请使用try\u cast()
。是的,我确实看过这个,并且试过了。但每当我的运行时间为47秒时,它就会显示为47毫秒。请尝试以下代码:选择(@run\u-time/1000000)%100作为小时,(@run\u-time/10000)%100作为分钟,(@run\u-time/100)%100作为秒,(@run\u-time%100)*10作为毫秒选择dateadd(小时,(@run\u-time/1000000)%100,dateadd(分钟,(@run\u-time/10000)%100,dateadd(秒,(@run\u-time/100)%100,dateadd(毫秒,(@run\u-time%100)*10,将('00:00:00'转换为时间(2‘)')))))同样,有了这段代码,我如何在没有from语句的情况下引用第一条select语句中的运行时间?参见我的新答案