的樣本數據:
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
),那麼它會嘗試應用任何有效的替換(第二個選擇i n Replacements
)。它將做的是繼續應用這第二個選擇,根據它產生的結果,直到沒有新的行產生。這被稱爲遞歸公用表表達式(CTE)。
然後,我們使用第二個CTE(這次是一個非遞歸函數)FinalReplacements
對第一個CTE產生的所有行進行編號,爲最後產生的行分配較低的行號。從邏輯上講,這些是應用上次適用轉換的結果,因此不再包含任何要替換的原始字符。因此,我們可以使用行號1對原始表執行更新。
該查詢確實做了比絕對必要的更多的工作 - 對於少量的替換字符行,它不太可能太低效。我們可以通過定義單一訂單來清除它,以便應用替代品。
其實,所有的更新換代確實是會發生 - 所有4個可能的結果計算,並行。然後SQL Server隨意將其中一個作爲「更新」應用。 –
此外,我已經將您的示例表標記爲試圖讓它們更易於閱讀的代碼 - 但我有點不確定哪些字符是示例數據的一部分,vs您可能添加了嘗試格式化它們。 –