Если открыто для TVF ...
Надоело извлекать строки (left, right, patindex, substrings, ...), я изменил функцию синтаксического анализа, чтобы принимать два не похожих на разделители
Будучи TVF, его легко использовать как CROSS APPLY
или как отдельное устройство.
Также не ясно, желаемых результатов. Если вам нужна одна строка, а не записи, вы можете легко объединить ее с помощью метода XML STUFF ().
Пример
Declare @S varchar(max) = '<blockquote class="twitter-tweet" data-lang="en"> *some text* </blockquote>"I must remain" <blockquote class="twitter-tweet" data-lang="en"> *some text again*</blockquote>"I must remain, too" <blockquote class="twitter-tweet" data-lang="en"> *some text again*</blockquote>'
Select * from [dbo].[tvf-Str-Extract](@S,'blockquote>','<blockquote')
Возвращает
RetSeq RetPos RetVal
1 77 "I must remain"
2 173 "I must remain, too"
UDF, если интересно
ALTER FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
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 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1)
From (
Select *,RetVal = Substring(@String, N, L)
From cte4
) A
Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters
Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/