SQL Server 2005. Я хочу, чтобы скрипт запускался в ближайшем будущем, когда мы будем готовы развернуть новое приложение. У нас есть много старых данных, которые должны быть перемещены в новые таблицы в новом приложении.
Одним из таких наборов данных являются часы выборки, введенные техническими специалистами, которые должны быть преобразованы в секунды в новом приложении.
Звучит достаточно просто, но приготовьтесь ... старое приложение не имело проверки . Новый столбец будет bigint, но старый столбец был varchar. Посмотрите на разные типы данных, с которыми я сталкивался часами.
24
24: 00
22: 57
24 часа
24ч
24 часа
22,3
24 ч.
н /
3,09
19
86394
86400 сек
24:00 действует: 19: 07
24 часа / действует = 13: 44
15: 8 (действительный = 15: 07)
Хорошо, так что сделайте глубокий вдох, это на самом деле не так уж плохо. Я уже проделал большую часть тяжелой работы (определяя различные шаблоны, которые использовали пользователи.) Это то, что до сих пор:
Я создаю функцию для повторного разбора формата ЧЧ или СС или ЧЧ: ММ продолжительности выборки.
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% работы. И я могу запросить крайние случаи и вычистить их вручную ... но я хочу избежать любой ручной работы.
Мне было интересно, есть ли у кого-нибудь лучшее решение, возможно, с меньшим количеством строк кода или избегающее создания функции.