suppose我在它们之间具有逗号的字符串,我想在第二到第7逗号之间找到字符串的长度,或者(n to n to n (。
我正在使用此步骤。
CREATE FUNCTION [dbo].[fn_split_1]
(
@sInputList VARCHAR(MAX), -- List of delimited items
@sDelimiter VARCHAR(5) = ',' -- Delimiter that separates items
)
RETURNS @List TABLE (id int,item VARCHAR(8000))
BEGIN
DECLARE @sItem VARCHAR(8000)
Declare @Count int
SET @Count =1
WHILE CHARINDEX(@sDelimiter, @sInputList, 0) <> 0
BEGIN
SELECT
@sItem = RTRIM(LTRIM(SUBSTRING(@sInputList, 1, CHARINDEX(@sDelimiter, @sInputList, 0) - 1))),
@sInputList = RTRIM(LTRIM(SUBSTRING(@sInputList, CHARINDEX(@sDelimiter, @sInputList, 0) + LEN(@sDelimiter), LEN(@sInputList))))
IF LEN(@sItem) > 0
INSERT INTO @List SELECT @Count ,@sItem
SET @Count =@Count +1
END
IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @Count ,@sInputList -- Put the last item in
SET @Count =@Count +1
RETURN
END
Select sum(len(item))+(7-2)as'LengthOfChar(b/w 2 and 7 comma)','abc,def,efg,hij,lkm,nop,qrs,tuv' as'String'
from [fn_split_1]('abc,def,efg,hij,lkm,nop,qrs,tuv',',') where Id<7 and id>2
输入和输出结果
Inputs String is : 'abc,def,efg,hij,lkm,nop,qrs,tuv'
String between 2nd and 7th comma : 'efg,hij,lkm,nop,qrs'
LengthOfChar(b/w 2 and 7 comma) : 19
The result from the function would be
ID Values
1 abc
2 def
3 efg
4 hij
5 lkm
6 nop
7 qrs
8 tuv
,但我们不能忽略文本之间的逗号。是否有更多优化的方法来实现这一目标?
bellow有一个基于xml&amp;的解决方案Xquery:
DECLARE @Source NVARCHAR(100) = N'abc,def,efg,hij,lkm,nop,qrs,tuv'
DECLARE @Start INT = 2
DECLARE @End INT = 7
-- Solution #1
SELECT
(CONVERT(XML, N'<root><i>' + REPLACE(@Source, N',', N'</i><i>') + N'</i></root>'))
.query(N'for $t in (root/i[position() gt sql:variable("@Start") and position() le sql:variable("@End")]/text())
return <len>{string-length($t)}</len>')
.value('sum(len)', 'INT') + (@End - @Start - 1)
演示
编辑1:用...query('...').query('sum(len)').value('.', 'INT')
替换CC_1
注意:假设是源字符串不包含XML保留的字符(例如<
(。让我知道这是否是您的情况。
首先,我会在拆分/解析功能中看到循环。
也就是说,此替代方案还将返回序列号
示例
声明 @yourtable表(字符串varchar(max((插入 @yourtable值('ABC,DEF,EFG,HIJ,LKM,NOP,QRS,TUV'(
Select A.*
,B.*
From @YourTable A
Cross Apply (
Select Value = sum(len(RetVal)+1)-1
From [dbo].[udf-Str-Parse-8K](A.String,',')
Where RetSeq between 2 and (7-1)
) B
返回
String Value
abc,def,efg,hij,lkm,nop,qrs,tuv 19
如果有兴趣
UDFCREATE FUNCTION [dbo].[udf-Str-Parse-8K] (@String varchar(max),@Delimiter varchar(25))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
只是为了娱乐
Select * From [dbo].[udf-Str-Parse-8K]('abc,def,efg,hij,lkm,nop,qrs,tuv',',')
返回
RetSeq RetVal
1 abc
2 def
3 efg
4 hij
5 lkm
6 nop
7 qrs
8 tuv
您需要拆分吗?您可以找到每个" nth"字符的位置并获得区别。
CREATE FUNCTION dbo.NthCharIndex
(
@CharToFind varchar(8000),
@StringToSearch varchar(8000),
@N int
)
RETURNS int
AS
BEGIN
DECLARE @pos int, @ctr int, @ret int
SET @pos = 0
SET @ctr = 0
BEGIN
WHILE(@ctr < @N)
BEGIN
SELECT @ret = CHARINDEX(@CharToFind, @StringToSearch, @pos + 1)
SET @ctr = @ctr + 1
SET @pos = @ret
END
END
RETURN(@ret)
END
GO
然后您只需要找到差异。
Select dbo.nthCharIndex('a', 'bananaBanana', 6) - dbo.nthCharIndex('a', 'bananaBanana', 1)