SQL Server 2005.当我们准备部署新应用程序时,我希望在不久的将来运行脚本。我们有许多旧数据必须移动到新应用程序中的新表中。
一组这样的数据是技术人员输入的小时数,必须在新应用中转换为秒。
听起来很容易,但要自己动手......旧的应用程序没有验证。新列将是bigint,但旧列是varchar。查看我几个小时内遇到的不同类型的数据。
24
24:00
22:57
24人力资源 24小时
24小时
22.3小时 24小时的时间 N / A
3.09
19个
86394个
86400秒
24:00有效:19:07
24小时/有效期= 13:44
15:8(有效期= 15:07)
好的,深吸一口气,实际上并不太糟糕。我已经完成了大部分的艰苦工作,(确定用户一直在使用的各种模式。)到目前为止这是:
我创建了一个重复解析HH或SS或HH:MM格式的采样持续时间的函数。
CREATE FUNCTION HoursToSecond(@input nvarchar(5))
RETURNS bigint
AS
BEGIN
DECLARE @return bigint
SELECT @return = CASE
WHEN ISNUMERIC(@input)=1
THEN CASE
WHEN CAST(@input AS decimal(9,3))<100
THEN CAST(@input as decimal(9,3))*3600 --convert hrs to secs
ELSE CAST(@input as bigint) --already in seconds
END
WHEN CHARINDEX(':',@input)>0
THEN CAST(left(@input,CHARINDEX(':',@input)-1) as int)*3600 +
CAST(SUBSTRING(@input,CHARINDEX(':',@input)+1,2) as int)*60
ELSE NULL
END
RETURN @return
END
然后我根据我在数据中看到的模式进行切换。
INSERT INTO NewDatasheets (sample_time)
SELECT
CASE
WHEN ISNUMERIC(samplingtime)=1 THEN dbo.HoursToSecond(samplingtime)
WHEN samplingtime LIKE '% %' THEN dbo.HoursToSecond(LEFT(samplingtime, CHARINDEX(' ',samplingtime)-1))
WHEN samplingtime LIKE '%h%' THEN dbo.HoursToSecond(LEFT(samplingtime, CHARINDEX('h',samplingtime)-1))
WHEN samplingtime LIKE '%:%' THEN dbo.HoursToSecond(samplingtime)
ELSE NULL
END
FROM OldDatasheets
丑陋的脚本工作。是。我甚至没有尝试解析“有效”之后的几个小时。但它将完成90%的工作。我可以查询边缘情况并手动清理它们......但我想避免任何手动工作。
我想知道是否有人有更好的解决方案,可能用更少的代码行或避免创建函数。
答案 0 :(得分:1)
因为这是一次性的工作,而不是一项正在进行的工作,所以它不一定是优雅的代码,或者坦率地甚至可以获取所有数据。它不需要维护,因此您几乎可以编写任何可行的内容,并且花费更长时间处理奇怪的稀疏度而不是单独更新它们是没有意义的,例如:
UPDATE Table SET NewValue=86400 WHEN OldValue='86400 Sec';
UPDATE Table SET NewValue=86400 WHEN OldValue='24 hrs / valid=13:44';
这样你至少可以一次性更新所有相同的案例,但这比尝试解析真正的奇怪事项要少得多。写下您可以处理的大部分案例(它看起来像你有),然后如上所述手动完成其余的工作。如果您发现任何模式,您可以编写脚本,然后通过任何方式编写脚本,但有时手动工作是正确的答案。