我的表中存有一个等式。我一次取一个方程式,并希望用任何其他字符替换所有运算符。
输入字符串: (N_100-(6858)*(6858)*N_100/0_2)%N_35
运营商或模式: (+, -, *, /, %, (, ))
替换字符: ~
输出字符串: ~N_100~~6858~~~6858~~N_100~0_2~~N_35
我尝试使用嵌套REPLACE 函数进行下面的查询,得到了所需的输出:
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
输出: ~N_100~~6858~~~6858~~N_100~0_2~~N_35
如何在不使用嵌套替换函数的情况下替换所有运算符?
答案 0 :(得分:12)
如果您使用表格来驱动它,我相信它更容易,更易读。
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
答案 1 :(得分:5)
在SQL Server中,Oracle的TRANSLATE函数没有等价,你必须使用嵌套的替换函数。
以下解决方案技术上正确:
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;
但我不明白为什么你会赞成这种情况而不是嵌套的REPLACE调用。
答案 2 :(得分:1)
最简单的方法是使用TRANSLATE
功能。它来自SQL Server 2017 (aka vNext)
及以上。
在第二个参数中指定的某些字符转换为目标字符集后,返回作为第一个参数提供的字符串。
TRANSLATE ( inputString, characters, translations)
返回与inputString相同类型的字符表达式,其中第二个参数中的字符将替换为第三个参数中的匹配字符。
在你的情况下:
SELECT TRANSLATE('(N_100-(6858)*(6858)*N_100/0_2)%N_35', '+-*/%()','~~~~~~~')
<强> DBFiddle Demo 强>
答案 3 :(得分:0)
我创建了一个SPLIT
函数来实现这个功能,因为我需要在PROCEDURE
分词功能
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
程序中使用的代码:
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
<强>输出强>
~N_100~~6858~~~6858~~N_100~0_2~~N_35
答案 4 :(得分:0)
您可以在不使用嵌套替换函数的情况下替换所有运算符
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