Выполнить регулярное выражение (заменить) в запросе SQL - PullRequest
16 голосов
/ 30 сентября 2008

Каков наилучший способ заменить все '& lt' на < в данном столбце базы данных? В основном выполняют s/&lt[^;]/</gi

Примечания:

  • должен работать в MS SQL Server 2000
  • Должен повторяться (и не заканчиваться <;;;;;;;;;)

Ответы [ 6 ]

15 голосов
/ 30 сентября 2008

Требуется некоторый взлом, но мы можем сделать это с LIKE , PATINDEX , LEFT AND RIGHT и старой доброй конкатенацией строк.

create table test
(
    id int identity(1, 1) not null,
    val varchar(25) not null
)

insert into test values ('&lt; <- ok, &lt <- nok')

while 1 = 1
begin
    update test
        set val = left(val, patindex('%&lt[^;]%', val) - 1) +
                      '&lt;' +
                      right(val, len(val) - patindex('%&lt[^;]%', val) - 2)
    from test
    where val like '%&lt[^;]%'

    IF @@ROWCOUNT = 0 BREAK
end

select * from test

Лучше то, что это не зависит от версии SQL Server и должно работать нормально.

10 голосов
/ 30 сентября 2008

Я думаю, что это можно сделать намного чище, если вы используете разные вещи:)

create table test
(
    id int identity(1, 1) not null,
    val varchar(25) not null
)

insert into test values ('&lt; <- ok, &lt <- nok')

WHILE 1 = 1
BEGIN
    UPDATE test SET
        val = STUFF( val , PATINDEX('%&lt[^;]%', val) + 3 , 0 , ';' )
    FROM test
    WHERE val LIKE '%&lt[^;]%'

    IF @@ROWCOUNT = 0 BREAK
END

select * from test
6 голосов
/ 30 сентября 2008

Как насчет:

    UPDATE tableName
    SET columName = REPLACE(columName , '&lt', '&lt;')
    WHERE columnName LIKE '%lt%'
    AND columnName NOT LIKE '%lt;%'

Edit:

Я только что понял, что будут игнорироваться столбцы с частично правильными &lt; строками.

В этом случае вы можете проигнорировать вторую часть предложения where и вызвать его позже:

    UPDATE tableName
    SET columName = REPLACE(columName , '&lt;;', '&lt;')
3 голосов
/ 30 сентября 2008

В этой статье рассказывается, как создать простую функцию Regex Replace, которую вы можете использовать в SQL 2000 (и 2005 с простой настройкой), которая может вам помочь.

1 голос
/ 03 января 2018

Очень специфично для этого шаблона, но я делал подобное в прошлом:

REPLACE(REPLACE(columName, '&lt;', '&lt'), '&lt', '&lt;')

более широкий пример (кодировать символы, которые могут быть неуместны в атрибуте TITLE)

REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    columName
    -- Remove existing encoding:
    , '&amp;', '&')
    , '&#34;', '"')
    , '&#39;', '''')
    -- Reinstate/Encode:
    , '&', '&amp;')
    -- Encode:
    , '"', '&#34;')
    , '''', '&#39;')
    , ' ', '%20')
    , '<', '%3C')
    , '>', '%3E')
    , '/', '%2F')
    , '\', '%5C')
1 голос
/ 30 сентября 2008

Если версия MSSQL для регулярных выражений поддерживает отрицательный прогноз, это был бы правильный путь к этому.

s/&lt(?!;)/&lt;/gi

отлавливает все экземпляры & lt , за которыми не следует ; (даже если за ними ничего не следует, что [^;] будет пропустить) и не фиксирует следующий не-; символ как часть матча, устраняя проблему, упомянутую в комментариях к исходному вопросу о том, что этот символ теряется при замене.

К сожалению, я не использую MSSQL, поэтому понятия не имею, поддерживает ли он отрицательный прогноз или нет ...

...