Given a table of replacements, can all the replacements be applied to a column in a table in the same query?
Disclaimer: I can do this with a cursor, or with dynamic sql to create a nested string of replacements; I want to know if it could be done concisely.
I have a replacements table,
create table #replacements(old varchar(max), new varchar(max))
insert into #replacements values
('X','Y'),
('A','B'),
('W','V'),
('C','D')
and a table of values to replace:
create table #value(value varchar(max))
insert into #value values
('XA'),
('WC')
I'd like to perform these in one query which gives back:
YB
VD
Is there any way to do this? I tried,
update v
set value = replace(value,old,new)
from #value v,
#replacements
but this gives (only the first row in the full join is done):
YA
WC
Temp tables for data sample
Data before update
Solution using dynamic query
Data after update
JBond's answer is simple but it's SLOW for any large number of rows since it will be RBAR. His function has to grab each value one by one and then run it through your replacement table. With a large number of rows, you'll see some serious performance issues.
Here's a dynamic query that is, in my opinion, a little simpler than Vasily's, although both really do the same thing. The code should perform really well for any number of rows. Try it out:
Recursive Solution
Compared to the dynamic SQL solution, this is not great. Compared to the function, it is better. What the recursion does is apply each change one by one to the entire dataset. So the row in replacement is applied to all the data. Then the second change(row) is applied to the entire dataset etc... So for a small number of changes because it goes through it RBAR, and then a not too large value set, it will work just fine.
I am giving this answer based on the assumption that the example is only using temporary tables for our convenience.
However, you could use a scalar function that does this for you.
Note - As mentioned above. This assumes that the table in the function does not need to be a temporary table.
Function:
This way you can just call the function directly from the
#value
.View the result set:
Output:
Apply the changes: