If you wont or maybe can't use a CLR
due to security reasons, there is a simple way using a CTE
inside standard t-sql.
Here is a complete example inclusive demo structure. You can run it on a whole table.
CREATE TABLE #dummyData(id int identity(1,1), teststring nvarchar(255))
INSERT INTO #dummyData(teststring)
VALUES(N'<B99_9>TEST</B99_9><LastDay>TEST</LastDay>, <B99_9>TEST</B99_9>, <B99_9></B99_9>')
DECLARE @starttag nvarchar(10) = N'<B99_9>', @endtag nvarchar(10) = N'</B99_9>'
;WITH cte AS(
SELECT id, STUFF(
teststring,
PATINDEX(N'%'+@starttag+N'[a-z0-9]%',teststring)+LEN(@starttag),
(PATINDEX(N'%[a-z0-9]'+@endtag+N'%',teststring)+1)-(PATINDEX(N'%'+@starttag+N'[a-z0-9]%',teststring)+LEN(@starttag)),
N''
) as teststring, 1 as iteration
FROM #dummyData
-- iterate until everything is replaced
UNION ALL
SELECT id, STUFF(
teststring,
PATINDEX(N'%'+@starttag+N'[a-z0-9]%',teststring)+LEN(@starttag),
(PATINDEX(N'%[a-z0-9]'+@endtag+N'%',teststring)+1)-(PATINDEX(N'%'+@starttag+N'[a-z0-9]%',teststring)+LEN(@starttag)),
N''
) as teststring, iteration+1 as iteration
FROM cte
WHERE PATINDEX(N'%'+@starttag+N'[a-z0-9]%',teststring) > 0
)
SELECT c.id, c.teststring
FROM cte as c
-- Join to get only the latest iteration
INNER JOIN (
SELECT id, MAX(iteration) as maxIteration
FROM cte
GROUP BY id
) as onlyMax
ON c.id = onlyMax.id
AND c.iteration = onlyMax.maxIteration
-- Cleanup
DROP TABLE #dummyData
If you want to use the result of the CTE
in an update. You can just replace the part after the CTE
-definition with the following code:
UPDATE dd
SET teststring = c.teststring
FROM #dummyData as dd -- rejoin the base table for later update usage
INNER JOIN cte as c
ON dd.id = c.id
-- Join to get only the latest iteration
INNER JOIN (
SELECT id, MAX(iteration) as maxIteration
FROM cte
GROUP BY id
) as onlyMax
ON c.id = onlyMax.id
AND c.iteration = onlyMax.maxIteration
If you don't want to run it on a complete table set, you can run the following code for a single variable:
DECLARE @string nvarchar(max) = N'<B99_9>TEST</B99_9><LastDay>TEST</LastDay>, <B99_9>TEST</B99_9>, <B99_9></B99_9>'
DECLARE @starttag nvarchar(10) = N'<B99_9>', @endtag nvarchar(10) = N'</B99_9>'
WHILE PATINDEX(N'%'+@starttag+N'[a-z0-9]%',@string) > 0 BEGIN
SELECT @string = STUFF(
@string,
PATINDEX(N'%'+@starttag+N'[a-z0-9]%',@string)+LEN(@starttag),
(PATINDEX(N'%[a-z0-9]'+@endtag+N'%',@string)+1)-(PATINDEX(N'%'+@starttag+N'[a-z0-9]%',@string)+LEN(@starttag)),
N''
)
END
SELECT @string