0

ここで提案されているインラインソリューション:文字列を分割してアイテムxにアクセスできるようにするにはどうすればよいですか?by vzczcは、再帰の深さの制限があるため、100未満の要素を含む文字列に対してのみ機能します(UDF内で制限を変更することはできません)。

長い文字列を優れたパフォーマンスで分割する他の方法はありますか?私が使用している(インラインではない)UDFは非常に遅いです:

CREATE FUNCTION [dbo].[fn_ParseDelimitedStrings](@String nvarchar(MAX), @Delimiter char(1))
RETURNS @Values TABLE
(
 RowId int Not Null IDENTITY(1,1) PRIMARY KEY
,Value nvarchar(255) Not Null
)
AS
BEGIN
    DECLARE  @startPos smallint
        ,@endPos smallint

    IF (@String = '')
    RETURN

    IF (RIGHT(@String, 1) != @Delimiter)
        SET @String = @String + @Delimiter
    SET @startPos = 1
    SET @endPos = CharIndex(@Delimiter, @String)
    WHILE @endPos > 0
    BEGIN
        INSERT @Values(Value)
        SELECT LTRIM(RTRIM(SUBSTRING(@String, @startPos, @endPos - @startPos)))
        -- remove the delimiter just used
        SET @String = STUFF(@String, @endPos, 1, '')
        -- move string pointer to next delimiter
        SET @startPos = @endPos
        SET @endPos = CHARINDEX(@Delimiter, @String)
    END
    RETURN
END
4

2 に答える 2

1

これがあなた自身の例と同じパフォーマンスを与えるかどうかはわかりませんが(おそらくそうなるでしょう)、私が使用しているものを試してみてください:

 CREATE FUNCTION [dbo].[UDF_Split]
 (
     @InputParam VARCHAR(4000),
     @delimiter CHAR(1)
 ) 
 RETURNS @tSplit TABLE (
 ItemValue VARCHAR(255)
 ) 
 AS

 BEGIN

-- Declares --
--------------

-- Variables.
DECLARE @ItemValue VARCHAR(255)


-- Initialize --
----------------

-- Make sure it has a trailing comma.
IF RIGHT(@InputParam, 1) <> @delimiter SELECT @InputParam = @InputParam + @delimiter 


-- Put values separated by delimiter in a string to a table as records.
WHILE CHARINDEX(@delimiter, @InputParam) <> 0
BEGIN 
    SELECT @ItemValue = CONVERT(VARCHAR(255), SUBSTRING(@InputParam, 1, CHARINDEX(@delimiter , @InputParam) -1))


    if DATALENGTH(@ItemValue) = 0
        SELECT @InputParam = SUBSTRING(@InputParam,2, len(@InputParam) - 1)
    else
    begin
        SELECT @InputParam = SUBSTRING(@InputParam, DATALENGTH(RTRIM(@InputParam)) - ((DATALENGTH(RTRIM(@InputParam)) - DATALENGTH(RTRIM(@ItemValue))) - 2), 4000) 

        INSERT  @tSplit 
        SELECT  CONVERT(VARCHAR(255), @ItemValue)
    end     


END 

-- Return --
------------
RETURN
END 
于 2012-11-07T16:05:39.117 に答える
1

関数を呼び出すときにヒントを使用してMAXRECURSION、要素が100未満の文字列しか分割できないという問題を解消できるため、使用したリンクの例を使用して、次のように呼び出すことができます。

-- CREATE A STRING TO SPLIT WITH OVER 100 DELIMITERS
DECLARE @s VARCHAR(1000) = 'a'

SELECT  @s = @s + ',a'
FROM    master..spt_values
WHERE   type= 'p'
AND     number BETWEEN 1 AND 150

--SPLIT LONG STRING
SELECT  *
FROM    dbo.splitString(@s, ',')
OPTION (MAXRECURSION 0) -- NO LIMIT
于 2012-11-07T16:42:29.920 に答える