在 SQL 中拆分长字符串
Posted
技术标签:
【中文标题】在 SQL 中拆分长字符串【英文标题】:Splitting long strings in SQL 【发布时间】:2012-11-07 15:57:28 【问题描述】:这里建议的内联解决方案:vzczc 的 How do I split a string so I can access item x? 仅适用于包含少于 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
【问题讨论】:
有大量的问题/答案来解决这个问题。你试过this solution using XML。 【参考方案1】:您可以在调用您的函数时使用MAXRECURSION
提示,以消除只能拆分少于100 个元素的字符串的问题,因此使用您使用过的link 中的示例可以调用:
-- 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
【讨论】:
最后我们采用了这个解决方案:***.com/a/240586/572769 它速度很快并且支持超过 4000 个字符的字符串。【参考方案2】:不确定这是否会为您提供与您自己的示例相同的性能(可能会),但请尝试我正在使用的一个:
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
【讨论】:
以上是关于在 SQL 中拆分长字符串的主要内容,如果未能解决你的问题,请参考以下文章
Oracle sql REGEXP 在某个点拆分字符串以保持含义 - 需要的建议