Разбор непроверенных десятичных знаков (varchar) в SQL Server - PullRequest
1 голос
/ 07 января 2010

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% работы. И я могу запросить крайние случаи и вычистить их вручную ... но я хочу избежать любой ручной работы.

Мне было интересно, есть ли у кого-нибудь лучшее решение, возможно, с меньшим количеством строк кода или избегающее создания функции.

1 Ответ

1 голос
/ 08 января 2010

Поскольку это единовременная работа со звуком вещей, а не постоянная работа, она не должна быть изящной частью кода или, честно говоря, даже собирать все данные. Его не нужно поддерживать, поэтому вы можете написать что-нибудь, что будет работать, и нет смысла тратить больше времени на обработку нечетных раритетов, чем на их индивидуальное обновление, например:

UPDATE Table SET NewValue=86400 WHEN OldValue='86400 Sec';
UPDATE Table SET NewValue=86400 WHEN OldValue='24 hrs / valid=13:44';

Таким образом, вы, по крайней мере, обновляете все идентичные случаи за один раз, но это гораздо меньше, чем попытка разобрать реальные странности. Напишите, что вы можете сделать, чтобы обработать большую часть дел (которые выглядят так, как у вас), и просто выполните остальные вручную, как описано выше. Если вы обнаружите какие-либо шаблоны, в которых вы можете написать сценарий, то обязательно запишите их, но иногда ручная работа - правильный ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...