2013-05-27 4 views
2

У меня есть проблема, у меня есть следующие строки строкРасщепление разделителями строки с неопределенным количеством разделителей

0009 - The Good Boy Song 
0003 - Alphabet Song 
0008 - Flame-thrower Guide 

У меня есть функция разделения, которая в настоящее время принимает два параметра,

ALTER FUNCTION [dbo].[Split] 
(
@String NVARCHAR(4000), 
@Delimiter NCHAR(1) 
) 
RETURNS TABLE 
AS 
RETURN 
(

WITH Split(stpos,endpos) 
AS(
    SELECT 0 AS stpos, CHARINDEX(@Delimiter2,@String) AS endpos 
    UNION ALL 
    SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1) 
     FROM Split 
     WHERE endpos > 0 
) 
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)), 
    'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos) 
FROM Split 
) 

мне нужно чтобы убедиться, что Ouput что-то вроде

Id  Data 
0009 The Good Boy Song 
0003 Alphabet Song 
0008 Flame-thrower Guide 

, а не что-то вроде

0009 The Good Boy Song 
0003 Alphabet Song 
0008 Flame 
thrower Guide 

Я использую это на SSRS, где я отправляю многозначный аргумент, он выглядит так, как SSRS отправляет несколько значений в форме CSV.

'0009 - The Good Boy Song,0003 - Alphabet Song,0008 - Flame-thrower Guide' 

Как я обновляю свою функцию для обработки этого сценария?

ответ

0

Я немного обновил вашу функцию:

ALTER FUNCTION [Split] 
(
@String NVARCHAR(4000), 
@Delimiter NCHAR(1) 
) 
RETURNS TABLE 
AS 
RETURN 
(

WITH Split(stpos,endpos) 
AS(
    SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos 
    UNION ALL 
    SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1) 
     FROM Split 
     WHERE endpos > 0 
) 
, SplitData AS 
(
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)), 
     'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos) 
    FROM Split 
) 
SELECT ID 
    , NumericData = SUBSTRING(Data, 1, 4) 
    , TextData = SUBSTRING 
    (
     Data 
     , 8 
     , len(Data) - 7 
    ) 
FROM SplitData 
) 

Это дает OK результаты для меня.

См. SQL Fiddle with demo.

Редактировать после комментария:

Чтобы избежать проблем с лимитом рекурсии вам нужно установить MAXRECURSION вне функции, то есть, когда вы вызываете его с SELECT заявлением:

SELECT * 
FROM dbo.Split 
(
    N'0009 - The Good Boy Song,0003 - Alphabet Song,0008 - Flame-thrower Guide' 
    , N',' 
) 
OPTION (MAXRECURSION 0) 

Вы не можете применить подсказку в функции, как она написана.

См. this Вопрос и this Обсуждение MSDN для получения дополнительной информации и других возможных обходных решений.

Еще один комментарий ... Если вы ожидаете длинные строки, возможно, вам стоит рассмотреть возможность изменения параметра от NVARCHAR(4000) до NVARCHAR(max)?

+0

[This] (http://sqlfiddle.com/#!3/5fe42/2) failed – Yaroslav

+0

В соответствии с вопросом строка исходит из многозначного параметра SSRS, который разделен запятой. Если OP подтверждает, что они нуждаются в вашем конкретном случае, я могу соответствующим образом обновить ответ. –

+0

Только так я думал ... Спасибо. –

Смежные вопросы