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?
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
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.
The easiest way is to use TRANSLATE
function. It is availble from SQL Server 2017 (aka vNext)
and above.
TRANSLATE
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', '+-*/%()','~~~~~~~')
DBFiddle Demo
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