4

つまり、1 つの文字列に対して複数の置換を実行できる単一の再帰クエリを探しています。私はそれができるという考えを持っていますが、頭を包むことができていません。

確かに、私はアプリケーションのビズ層、または CLR でさえ置き換えを行うことを好みますが、これらはこの場合のオプションではありません。

より具体的には、以下の混乱 (8 つの異なるストアド プロシージャの C&P) を TVF に置き換えたいと考えています。

SET @temp = REPLACE(RTRIM(@target), '~', '-')
SET @temp = REPLACE(@temp, '''', '-')
SET @temp = REPLACE(@temp, '!', '-')
SET @temp = REPLACE(@temp, '@', '-')
SET @temp = REPLACE(@temp, '#', '-')
-- 23 additional lines reducted
SET @target = @temp

これが私が始めたところです:

-- I have a split string TVF called tvf_SplitString that takes a string 
-- and a splitter, and returns a table with one row for each element.
-- EDIT: tvf_SplitString returns a two-column table: pos, element, of which
--       pos is simply the row_number of the element.
SELECT REPLACE('A~B!C@D@C!B~A', MM.ELEMENT, '-') TGT
FROM   dbo.tvf_SplitString('~-''-!-@-#', '-') MM

問題のあるすべての文字を「-」で区切られた単一の文字列に結合したことに注意してください (「-」が問題の文字の 1 つになることは決してないことがわかっています)。このクエリの結果は次のようになります。

TGT
------------
A-B!C@D@C!B-A
A~B!C@D@C!B~A
A~B-C@D@C-B~A
A~B!C-D-C!B~A
A~B!C@D@C!B~A

したがって、置換は明らかに機能しますが、再帰的にしたいので、トップ 1 をプルして、最終的には次のようになります。

TGT
------------
A-B-C-D-C-B-A

1 つのクエリでこれを達成する方法についてのアイデアはありますか?

編集:別の方法があれば、実際の再帰は必要ありません。ここでも数表の使用を考えています。

4

2 に答える 2

8

これをスカラー関数で使用できます。一部の外部入力からすべての制御文字を削除するために使用します。

SELECT @target = REPLACE(@target, invalidChar, '-')
FROM (VALUES ('~'),(''''),('!'),('@'),('#')) AS T(invalidChar)
于 2016-01-26T02:48:43.260 に答える
5

私はそれを考え出した。tvf_SplitString 関数が行番号を「pos」として返すことについては言及しませんでした (ただし、row_number を割り当てるサブクエリも機能する可能性があります)。そのため、再帰呼び出しと分割の間の相互結合を制御できました。

-- the cast to varchar(max) matches the output of the TVF, otherwise error.
-- The iteration counter is joined to the row number value from the split string
-- function to ensure each iteration only replaces on one character.
WITH XX AS (SELECT CAST('A~B!C@D@C!B~A' AS VARCHAR(MAX)) TGT, 1 RN
            UNION ALL
            SELECT REPLACE(XX.TGT, MM.ELEMENT, '-'), RN + 1 RN
            FROM   XX, dbo.tvf_SplitString('~-''-!-@-#', '-') MM
            WHERE  XX.RN = MM.pos)
SELECT TOP 1 XX.TGT  
FROM   XX
ORDER  BY RN DESC

それでも、私は他の提案を受け入れます。

于 2012-04-05T23:48:07.813 に答える