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 ('"',';','*','?')

しかし、更新ごとに 1 つの交換しか行われないため、役に立ちません。

1 つの解決策は、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)から開始し、次に有効な置換を適用しようとします(の2番目の選択Replacements)。新しい行が生成されなくなるまで、生成された結果に基づいて、この2番目の選択を適用し続けます。これは、再帰共通テーブル式(CTE)と呼ばれます。

次に、2番目の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 に答える