2017-12-14 13 views
2

nvarchar(max)列の複数の部分文字列を置き換える必要があります。部分文字列と対応する置換値のリストは別のテーブルにあります。 UPDATE文をJOINで実行し、宛先表の行ごとに複数の部分文字列を置き換えると、置換は1回だけ行われます。UPDATEでJOINを使用して更新先の列を1回のみ

以下

は、問題を示すサンプルコードで、id=1rev=1のために、私は先のテーブルに置き換えるための2つの値を持っていることに注意してください。

CREATE TABLE dbo.replacements 
    (
    id   INT NOT NULL, 
    rev   INT NOT NULL, 
    target  NVARCHAR(50) NOT NULL, 
    replacement NVARCHAR(50) NOT NULL, 
) 
go 

INSERT INTO dbo.replacements VALUES (1, 1, 'abc', '123'); 
INSERT INTO dbo.replacements VALUES (1, 1, 'xyz', '789'); 
INSERT INTO dbo.replacements VALUES (2, 1, 'jkf', '321'); 
go 

CREATE TABLE dbo.destination 
    (
    id   INT NOT NULL, 
    rev   INT NOT NULL, 
    description NVARCHAR(max) NOT NULL 
) 
go 

INSERT INTO dbo.destination VALUES (1, 1, 'These two strings abc and xyz are to be replaced'); 
INSERT INTO dbo.destination VALUES (2, 1, 'This text jkf is to be replaced'); 
go 

SELECT * 
FROM dbo.replacements m 
     INNER JOIN dbo.destination d ON m.id = d.id AND m.rev = d.rev 

UPDATE d 
SET d.description = Replace(d.description, m.target, m.replacement) 
FROM dbo.destination d 
     INNER JOIN dbo.replacements m ON m.id = d.id AND m.rev = d.rev 

SELECT * 
FROM dbo.replacements m 
     INNER JOIN dbo.destination d ON m.id = d.id AND m.rev = d.rev 

行1の値'These two strings 123 and 789 are to be replaced'を取得することが期待され、実際の交換結果は次のとおりです。

id   rev   description 
----------- ----------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
1   1   These two strings 123 and xyz are to be replaced 
1   1   These two strings 123 and xyz are to be replaced 
2   1   This text 321 is to be replaced 

ご意見は大変ありがとうございます。

EDIT:

同じ行の2つ以上の置換があるかもしれません。

答えて

1

私は最適化と清潔さに関しては、この上の多くの時間を費やすことはありませんでしたが、私は、ネストされた置き換えをするだろう、と別の追加参加:

CREATE TABLE #replacements 
    (
    id   INT NOT NULL, 
    rev   INT NOT NULL, 
    target  NVARCHAR(50) NOT NULL, 
    replacement NVARCHAR(50) NOT NULL, 
) 
go 

INSERT INTO #replacements VALUES (1, 1, 'abc', '123'); 
INSERT INTO #replacements VALUES (1, 1, 'xyz', '789'); 
INSERT INTO #replacements VALUES (2, 1, 'jkf', '321'); 
go 

CREATE TABLE #destination 
    (
    id   INT NOT NULL, 
    rev   INT NOT NULL, 
    description NVARCHAR(max) NOT NULL 
) 
go 

INSERT INTO #destination VALUES (1, 1, 'These two strings abc and xyz are to be replaced'); 
INSERT INTO #destination VALUES (2, 1, 'This text jkf is to be replaced'); 
go 

SELECT * 
FROM #replacements m 
     INNER JOIN #destination d ON m.id = d.id AND m.rev = d.rev 

UPDATE d 
SET d.description = Replace(REPLACE(d.description, m.target, m.replacement), m2.target, m2.replacement) 
FROM #replacements m 
     INNER JOIN #destination d ON m.id = d.id AND m.rev = d.rev 
     INNER JOIN #replacements m2 ON m2.id = d.id AND m2.id = d.rev 
WHERE m.target <> m2.target 

SELECT * 
FROM #replacements m 
     INNER JOIN #destination d ON m.id = d.id AND m.rev = d.rev 
+0

にする必要がある3つ目の値がある場合にはどうなりますか交換された? –

+0

dfundako、あなたの答えを感謝しますが、@Sean Langeが言及したように - 置換の数は2以上であることができます(そして、しばしばです)。私はカーソルが行く唯一の方法だと思っています.... :( –

+0

あなたはこれのためのカーソルを必要としません。私はトリックを行ういくつかの動的SQLをノックアウトすることができると思う。 –

関連する問題