Вопрос по – Рекурсивная замена из таблицы символов

3

Короче говоря, я ищу один рекурсивный запрос, который может выполнять несколько замен в одной строке. У меня есть представление, что это можно сделать, но я не могу обернуть голову вокруг этого.

Конечно, я бы предпочел, чтобы замену выполнял бизнес-уровень приложения или даже CLR, но в данном случае это не варианты.

Более конкретно, я хочу заменить приведенный ниже беспорядок - C & amp; P в 8 различных хранимых процедурах - на 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('[email protected]@C!B~A', MM.ELEMENT, '-') TGT
FROM   dbo.tvf_SplitString('~-''[email protected]#', '-') MM

Обратите внимание, что я соединил все оскорбительные символы в одну строку, разделенную «-». (зная, что «-» никогда не будет одним из оскорбительных символов), который затем разделяется. Результат этого запроса выглядит так:

TGT
------------
[email protected]@C!B-A
[email protected]@C!B~A
[email protected]@C-B~A
A~B!C-D-C!B~A
[email protected]@C!B~A

Итак, замена явно работает, но теперь я хочу, чтобы она была рекурсивной, чтобы я мог вытащить верхнюю 1 и в итоге получить:

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

Любые идеи о том, как сделать это с помощью одного запроса?

РЕДАКТИРОВАТЬ: Ну, реальная рекурсия не требуется, если есть другой способ. Я тоже думаю об использовании таблицы чисел.

Ваш Ответ

2   ответа
4

что функция tvf_SplitString возвращает номер строки как & quot; pos & quot; (хотя подзапрос, присваивающий 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('[email protected]@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('~-''[email protected]#', '-') MM
            WHERE  XX.RN = MM.pos)
SELECT TOP 1 XX.TGT  
FROM   XX
ORDER  BY RN DESC

Тем не менее, я открыт для других предложений.

4

аления всех управляющих символов с какого-либо внешнего ввода.

SELECT @target = REPLACE(@target, invalidChar, '-')
FROM (VALUES ('~'),(''''),('!'),('@'),('#')) AS T(invalidChar)
Error: User Rate Limit Exceeded Griffin

Похожие вопросы