TSQL UDF для разделения строки каждые 8 ​​символов

Кто-то решил собрать несколько раз в один столбец, поэтому значение столбца может выглядеть так:

08:00 AM01:00 PM

И еще один столбец содержит дату в следующем формате;

20070906

Я хочу написать UDF для нормализации этих данных в одном запросе SQL, чтобы я мог вернуть 2 строки типа datetime для приведенного выше примера.

2007-09-06 08:00:00.000
2007-09-06 13:00:00.000

Преобразование в тип datetime простое ... но мне нужно разделить временную часть каждые 8 ​​символов, чтобы получить индивидуальный тайм-аут.

Кто-нибудь знает о существующем UDF для этого?


person Jeff    schedule 21.05.2011    source источник
comment
что не так с использованием SUBSTRING? msdn.microsoft.com/en-us/library/ms187748.aspx   -  person Mitch Wheat    schedule 21.05.2011
comment
КАЖДЫЕ 8 символов, а не только 8 символов. SUBSTRING создает одну строку.   -  person Jeff    schedule 21.05.2011
comment
Я это прекрасно знаю. предлагаю вызвать его несколько раз .... как в цикле!   -  person Mitch Wheat    schedule 21.05.2011


Ответы (2)


Попробуйте это, он разделит вашу строку на части указанной длины:

create function SplitString
(   
    @str varchar(max),
    @length int
)
returns @Results table( Result varchar(50) ) 
AS
begin
    declare @s varchar(50)
    while len(@str) > 0
    begin
        set @s = left(@str, @length)
        set @str = right(@str, len(@str) - @length)
        insert @Results values (@s)
    end
    return 
end

Например:

select * from dbo.SplitString('08:00 AM01:00 PM', 8)

Дадим такой результат:

Результат

08:00 AM

01:00 PM

person Chris Fulstow    schedule 21.05.2011
comment
Как бы вы посоветовали мне присоединить это к исходной таблице? - person Jeff; 21.05.2011
comment
Большая ошибка. Попробуйте установить длину больше 4 и увидите, что расчет перешел в неограниченное количество и не может получить результат. Я проверил его и проверил ниже @Rhyno way и обнаружил, что его решение работает нормально. - person QMaster; 20.10.2014

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

CREATE function SplitString
(   
    @str varchar(max),
    @length int
)
RETURNS @Results TABLE( Result varchar(50),Sequence INT ) 
AS
BEGIN

DECLARE @Sequence INT 
SET @Sequence = 1

    DECLARE @s varchar(50)
    WHILE len(@str) > 0
    BEGIN
        SET @s = left(@str, @length)
        INSERT @Results VALUES (@s,@Sequence)

        IF(len(@str)<@length)
        BREAK

        SET @str = right(@str, len(@str) - @length)
        SET @Sequence = @Sequence + 1
    END
    RETURN 
END
person Rhyno van der Sluijs    schedule 08.02.2013
comment
+1 Офигенный мужик. Я пробовал какое-то решение, но некоторые из них не работают или плохо работают на большой или маленькой длине. Вы исправили принятый ответ, и ваш способ работает. это еще одно из других решений, получившее знак принятия, но бесполезное. stackoverflow.com/questions/10852612/, и я хочу написать ответ для этого на основе вашего решения, если вы не возражаете. Спасибо еще раз. - person QMaster; 20.10.2014