我有一个包含以下数据的表'tblRandomString':
ID ItemValue
1 *Test"
2 ?Test*
我还有另一个表'tblSearchCharReplacement',其中包含以下数据
Original Replacement
* `star`
? `quest`
" `quot`
; `semi`
现在,我想使用这些替换在ItemValues中进行替换。 我试过这个:
Update T1
SET ItemValue = select REPLACE(ItemValue,[Original],[Replacement])
FROM dbo.tblRandomString T1
JOIN
dbo.tblSpecialCharReplacement T2
ON T2.Original IN ('"',';','*','?')
但它对我没有帮助,因为每次更新只进行一次替换。
我可以使用一种解决方案作为CTE来执行多次替换(如果存在的话)。
有更简单的方法吗?
答案 0 :(得分:2)
示例数据:
declare @RandomString table (ID int not null,ItemValue varchar(500) not null)
insert into @RandomString(ID,ItemValue) values
(1,'*Test"'),
(2,'?Test*')
declare @SearchCharReplacement table (Original varchar(500) not null,Replacement varchar(500) not null)
insert into @SearchCharReplacement(Original,Replacement) values
('*','`star`'),
('?','`quest`'),
('"','`quot`'),
(';','`semi`')
UPDATE
:
;With Replacements as (
select
ID,ItemValue,0 as RepCount
from
@RandomString
union all
select
ID,SUBSTRING(REPLACE(ItemValue,Original,Replacement),1,500),rs.RepCount+1
from
Replacements rs
inner join
@SearchCharReplacement scr
on
CHARINDEX(scr.Original,rs.ItemValue) > 0
), FinalReplacements as (
select
ID,ItemValue,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY RepCount desc) as rn
from
Replacements
)
update rs
set ItemValue = fr.ItemValue
from
@RandomString rs
inner join
FinalReplacements fr
on
rs.ID = fr.ID and
rn = 1
产生:
select * from @RandomString
ID ItemValue
----------- -----------------------
1 `star`Test`quot`
2 `quest`Test`star`
这样做是从未更改的文本(Replacements
中的顶部选择)开始,然后它尝试应用任何有效的替换(Replacements
中的第二个选择)。它将做的是根据它产生的任何结果继续应用第二个选择,直到没有产生新的行。这称为递归公用表表达式(CTE)。
然后我们使用第二个CTE(这次是非递归的)FinalReplacements
来对第一个CTE产生的所有行进行编号,将较低的行号分配给最后生成的行。从逻辑上讲,这些是应用最后一个适用变换的结果,因此将不再包含要替换的任何原始字符。因此,我们可以使用行号1对原始表执行更新。
这个查询确实做了比严格必要的工作更多的工作 - 对于少量的替换字符行,它不太可能效率太低。我们可以通过定义应用替换的单个订单来清除它。
答案 1 :(得分:0)
跳过连接表并嵌套REPLACE函数有效吗? 或者您是否需要实际从其他表中获取数据?
-- perform 4 replaces in a single update statement
UPDATE T1
SET ItemValue = REPLACE(
REPLACE(
REPLACE(
REPLACE(
ItemValue,'*','star')
ItemValue,'?','quest')
ItemValue,'"','quot')
ItemValue,';','semi')
注意:我不确定您是否需要转义任何要替换的字符