サンプルデータ:
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
)から開始し、次に有効な置換を適用しようとします(の2番目の選択Replacements
)。新しい行が生成されなくなるまで、生成された結果に基づいて、この2番目の選択を適用し続けます。これは、再帰共通テーブル式(CTE)と呼ばれます。
次に、2番目のCTE(今回は非再帰的なCTE)を使用しFinalReplacements
て、最初のCTEによって生成されたすべての行に番号を付け、最後に生成された行に低い行番号を割り当てます。論理的には、これらは最後に適用可能な変換を適用した結果である行であるため、置き換えられる元の文字は含まれなくなります。したがって、行番号1を使用して、元のテーブルに対して更新を実行し直すことができます。
このクエリは、厳密に必要な以上の作業を実行します。置換文字の行数が少ない場合は、非効率的ではない可能性があります。置換を適用する単一の順序を定義することで、それをクリアすることができます。