使用未定义数量的分隔符拆分分隔的字符串

时间:2013-05-27 08:40:11

标签: tsql reporting-services multiple-value

我有问题,我有以下字符串

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
)

我需要确保输出类似于

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'

我如何更新我的函数来处理这种情况?

1 个答案:

答案 0 :(得分: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
)

这给我带来了不错的结果。

请参阅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 SO问题和this MSDN讨论。

还有一条评论......如果您期望长字符串,也许您应该考虑将参数从NVARCHAR(4000)更改为NVARCHAR(max)