If you need extract from really big string small strings which are limited by delimiters, so for you can be useful this example:
DECLARE @text AS NVARCHAR (MAX) = '***[ddd]***
dfdf
fdfdfdfdfdf
***[fff]***
4545445
45454
***[ahaASSDAD]***
DFDFDF
***[SOME TEXT
';
DECLARE @PatBegin AS VARCHAR (1000) = '***[';
DECLARE @PatEnd AS VARCHAR (1000) = ']***';
WITH C1
AS (SELECT 0 AS Num
UNION ALL
SELECT 0),
C2
AS (SELECT C1.Num
FROM C1 CROSS JOIN C1 AS C2),
C3
AS (SELECT C2.Num
FROM C2 CROSS JOIN C2 AS C3),
C4
AS (SELECT C3.Num
FROM C3 CROSS JOIN C3 AS C4),
C5
AS (SELECT C4.Num
FROM C4 CROSS JOIN C4 AS C5),
numbers
AS (SELECT ROW_NUMBER() OVER ( ORDER BY o.Num) AS Number
FROM C5 AS o),
counts
AS (SELECT COUNT(*) AS CNT
FROM numbers
WHERE PATINDEX(@PatEnd, @TExt) = 1),
c
AS (SELECT N.Number AS CHARBegin
FROM numbers AS N
--CROSS JOIN numbers N2
WHERE SUBSTRING(@text, N.Number, LEN(@PatBegin)) = @PatBegin),
d
AS (SELECT c.CHARBegin,
T.CHARBegin AS CharEnd,
ISNULL(c.CHARBegin + LEN(@PatBegin) + NULLIF (CHARINDEX(@PatEnd, SUBSTRING(@text, c.CHARBegin + 1, ISNULL(T.CHARBegin, 2E7) - C.CHARBegin)), 0), 2e7) AS FactEnd
FROM c OUTER APPLY (SELECT TOP 1 C2.CHARBegin
FROM C AS C2
WHERE C2.CHARBegin > C.CharBegin) AS T)
SELECT SUBSTRING(@text, d.CHARBegin + LEN(@PatBegin), d.FactEnd - [d].[CHARBegin] - LEN(@PatBegin) - LEN(@PatEnd)) AS String_OUT,
[d].CHARBegin
FROM d;
here you have 2 delimiter - @PatBegin and @PatEnd - begin and end delimiters.
Result here will be:
UPDATE (09-01-2012)
Fixed logic to handle lack of last closing delimiter
No comments:
Post a Comment