Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive replace from a table of characters

In short, I am looking for a single recursive query that can perform multiple replaces over one string. I have a notion it can be done, but am failing to wrap my head around it.

Granted, I'd prefer the biz-layer of the application, or even the CLR, to do the replacing, but these are not options in this case.

More specifically, I want to replace the below mess - which is C&P in 8 different stored procedures - with a TVF.

SET @temp = REPLACE(RTRIM(@target), '~', '-')
SET @temp = REPLACE(@temp, '''', '-')
SET @temp = REPLACE(@temp, '!', '-')
SET @temp = REPLACE(@temp, '@', '-')
SET @temp = REPLACE(@temp, '#', '-')
-- 23 additional lines reducted
SET @target = @temp

Here is where I've started:

-- I have a split string TVF called tvf_SplitString that takes a string 
-- and a splitter, and returns a table with one row for each element.
-- EDIT: tvf_SplitString returns a two-column table: pos, element, of which
--       pos is simply the row_number of the element.
SELECT REPLACE('A~B!C@D@C!B~A', MM.ELEMENT, '-') TGT
FROM   dbo.tvf_SplitString('~-''-!-@-#', '-') MM

Notice I've joined all the offending characters into a single string separated by '-' (knowing that '-' will never be one of the offending characters), which is then split. The result from this query looks like:

TGT
------------
A-B!C@D@C!B-A
A~B!C@D@C!B~A
A~B-C@D@C-B~A
A~B!C-D-C!B~A
A~B!C@D@C!B~A

So, the replace clearly works, but now I want it to be recursive so I can pull the top 1 and eventually come out with:

TGT
------------
A-B-C-D-C-B-A

Any ideas on how to accomplish this with one query?

EDIT: Well, actual recursion isn't necessary if there's another way. I'm pondering the use of a table of numbers here, too.

like image 678
Griffin Avatar asked Dec 13 '22 03:12

Griffin


1 Answers

You can use this in a scalar function. I use it to remove all control characters from some external input.

SELECT @target = REPLACE(@target, invalidChar, '-')
FROM (VALUES ('~'),(''''),('!'),('@'),('#')) AS T(invalidChar)
like image 57
Nicholas Avatar answered Dec 22 '22 01:12

Nicholas