Reputation: 29051
I have an equation stored in my table. I am fetching one equation at a time and want to replace all the operators with any other character.
Input String: (N_100-(6858)*(6858)*N_100/0_2)%N_35
Operators or patterns: (+, -, *, /, %, (, ))
Replacement character: ~
Output String: ~N_100~~6858~~~6858~~N_100~0_2~~N_35
I had tried below query with Nested REPLACE Functions and I got desired output:
DECLARE @NEWSTRING VARCHAR(100)
SET @NEWSTRING = '(N_100-(6858)*(6858)*N_100/0_2)%N_35' ;
SELECT @NEWSTRING = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
@NEWSTRING, '+', '~'), '-', '~'), '*', '~'), '/', '~')
, '%', '~'), '(', '~'), ')', '~')
PRINT @NEWSTRING
Output: ~N_100~~6858~~~6858~~N_100~0_2~~N_35
How can I replace all the operators without using nested replace functions?
Upvotes: 6
Views: 47223
Reputation: 1
you can replace all the operators without using nested replace functions
DECLARE @Pattern VARCHAR(300) ='%[+-\*/%()]%';
DECLARE @String VARCHAR(300) ='(N_100-(6858)*(6858)*N_100/0_2)%N_35';
WHILE PatIndex(@Pattern, @String) <> 0
SELECT @String=Replace(@String, Substring(@String, PatIndex(@Pattern, @String), 1), '~')
SELECT @String
Upvotes: 0
Reputation: 175736
The easiest way is to use TRANSLATE
function. It is availble from SQL Server 2017 (aka vNext)
and above.
Returns the string provided as a first argument after some characters specified in the second argument are translated into a destination set of characters.
TRANSLATE ( inputString, characters, translations)
Returns a character expression of the same type as inputString where characters from the second argument are replaced with the matching characters from third argument.
In your case:
SELECT TRANSLATE('(N_100-(6858)*(6858)*N_100/0_2)%N_35', '+-*/%()','~~~~~~~')
Upvotes: 2
Reputation: 121
I believe it is easier and more readable if you use a table to drive this.
declare @String varchar(max) = '(N_100-(6858)*(6858)*N_100/0_2)%N_35'
--table containing values to be replaced
create table #Replace
(
StringToReplace varchar(100) not null primary key clustered
,ReplacementString varchar(100) not null
)
insert into #Replace (StringToReplace, ReplacementString)
values ('+', '~')
,('-', '~')
,('*', '~')
,('/', '~')
,('%', '~')
,('(', '~')
,(')', '~')
select @String = replace(@String, StringToReplace, ReplacementString)
from #Replace a
select @String
drop table #Replace
Upvotes: 12
Reputation: 29051
I had created a SPLIT
function to implement this because I need to implement this operation multiple time in PROCEDURE
SPLIT FUNCTION
create function [dbo].[Split](@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
Code used in procedure:
DECLARE @NEWSTRING VARCHAR(100)
SET @NEWSTRING = '(N_100-(6858)*(6858)*N_100/0_2)%N_35' ;
SELECT @NEWSTRING = REPLACE(@NEWSTRING, items, '~') FROM dbo.Split('+,-,*,/,%,(,)', ',');
PRINT @NEWSTRING
OUTPUT
~N_100~~6858~~~6858~~N_100~0_2~~N_35
Upvotes: 0
Reputation: 1994
There is not equivalent for the TRANSLATE function from Oracle in SQL Server, you have to use nested replace functions.
The following solution is technically correct:
DECLARE @newstring VARCHAR(100) = '(N_100-(6858)*(6858)*N_100/0_2)%N_35';
DECLARE @pattern VARCHAR(100) = '%[+-\*/%()]%';
DECLARE @i INT;
BEGIN
SET @i = PATINDEX(@pattern,@newstring)
WHILE @i <> 0
BEGIN
SET @newstring = LEFT(@newstring,@i-1) + '~' + SUBSTRING(@newstring,@i+1,100);
SET @i = PATINDEX(@pattern,@newstring)
END
SELECT @newstring;
END;
But I do not see why you would favor this over nested REPLACE calls.
Upvotes: 5