检索两个分隔符之间多次出现的字符串 SQL 服务器
Retrieve String Between Two Delimiters for Multiple Occurences SQL Server
如何从下方获取结果集 TESTING1、TESTING2
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'
基本上我需要获取 $I10~ 和 $
之间的所有子字符串
查看内联评论以了解正在发生的事情的概述:
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
select
--take part of
substring(
--the input string
@MyString
--starting from the first pre-delimiter (but add on the length of the delimeter so we exclude the delimeter itself)
,charindex(@pre,@MyString) + len(@pre)
--and ending at the first post-delimiter to appear after the first pre-delimeter
, charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre)) - (charindex(@pre,@MyString) + len(@pre))
)
,
--for the second result do the same as above
substring(
@MyString
--only now we're looking for the second pre-delimiter (aka the first after the first)
,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)
--and the second post-delimiter
,charindex(@post,@MyString,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)) - (charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre))
)
注意:这假设前置分隔符没有出现在前置分隔符和 post 分隔符之间;如果这样做可能会造成混淆/我们需要确定所需的行为。
substring(@stringToBreakApart, @indexOfFirstCharacterInSubstring, @lengthOfResultingString)
- return是原始字符串的一段。
charindex(@stringToFind, @stringToSearch, @indexOfFirstCharacterToLookAt)
- returns 给定字符串中给定子字符串的第一个字符的索引。
len(@stringToAnalyze)
- returns 给定字符串的字符数(长度)。
更新
根据评论,这里是如何 return 一个单独的列,它在分隔符上拆分字符串(忽略任何不在前和 post 之间的内容),然后连接结果以形成逗号分隔场.
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~$I10~TESTING3$...'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
, @newDelim char(1) = ','
;with cte(indx, firstCharIndex, lastCharIndex) as
(
select 0
, charindex(@pre,@MyString) + len(@pre)
, charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre))
union all
select indx + 1
, charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre)
, charindex(@post,@MyString,charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre))
from cte
where charindex(@pre,@MyString, lastCharIndex + len(@post)) > 0
)
, cte2 (substr, indx ) as
(
select cast(substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) as nvarchar(max))
, indx
from cte
where indx = (select max(indx) from cte)
union all
select substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) + @newDelim + cte2.substr
, cte.indx
from cte
inner join cte2 on cte2.indx = cte.indx + 1
)
select * from cte2 where indx = 0
如何从下方获取结果集 TESTING1、TESTING2
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'
基本上我需要获取 $I10~ 和 $
之间的所有子字符串查看内联评论以了解正在发生的事情的概述:
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
select
--take part of
substring(
--the input string
@MyString
--starting from the first pre-delimiter (but add on the length of the delimeter so we exclude the delimeter itself)
,charindex(@pre,@MyString) + len(@pre)
--and ending at the first post-delimiter to appear after the first pre-delimeter
, charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre)) - (charindex(@pre,@MyString) + len(@pre))
)
,
--for the second result do the same as above
substring(
@MyString
--only now we're looking for the second pre-delimiter (aka the first after the first)
,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)
--and the second post-delimiter
,charindex(@post,@MyString,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)) - (charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre))
)
注意:这假设前置分隔符没有出现在前置分隔符和 post 分隔符之间;如果这样做可能会造成混淆/我们需要确定所需的行为。
substring(@stringToBreakApart, @indexOfFirstCharacterInSubstring, @lengthOfResultingString)
- return是原始字符串的一段。
charindex(@stringToFind, @stringToSearch, @indexOfFirstCharacterToLookAt)
- returns 给定字符串中给定子字符串的第一个字符的索引。
len(@stringToAnalyze)
- returns 给定字符串的字符数(长度)。
更新
根据评论,这里是如何 return 一个单独的列,它在分隔符上拆分字符串(忽略任何不在前和 post 之间的内容),然后连接结果以形成逗号分隔场.
DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~$I10~TESTING3$...'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
, @newDelim char(1) = ','
;with cte(indx, firstCharIndex, lastCharIndex) as
(
select 0
, charindex(@pre,@MyString) + len(@pre)
, charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre))
union all
select indx + 1
, charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre)
, charindex(@post,@MyString,charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre))
from cte
where charindex(@pre,@MyString, lastCharIndex + len(@post)) > 0
)
, cte2 (substr, indx ) as
(
select cast(substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) as nvarchar(max))
, indx
from cte
where indx = (select max(indx) from cte)
union all
select substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) + @newDelim + cte2.substr
, cte.indx
from cte
inner join cte2 on cte2.indx = cte.indx + 1
)
select * from cte2 where indx = 0