1

我有一个包含以下数据的表'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 来执行多个替换(如果存在)。

有没有更简单的方法?

4

2 回答 2

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 行来对原始表执行更新。

这个查询确实做了比严格必要的工作更多的工作——对于少量的替换字符行,它不太可能效率太低。我们可以通过定义应用替换的单一顺序来清除它。

于 2012-09-10T07:22:16.867 回答
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')

注意:我不确定您是否需要转义要替换的任何字符

于 2015-04-01T01:04:42.063 回答