web-dev-qa-db-fra.com

Effectuer l'expression régulière (remplacer) dans une requête SQL

Quelle est la meilleure façon de remplacer tous les '& lt' par < dans une colonne de base de données donnée? Effectuez essentiellement s/&lt[^;]/</gi

Remarques:

  • doit fonctionner dans MS SQL Server 2000
  • Doit être répétable (et ne pas se retrouver avec <;;;;;;;;;)
17
alumb

Quelques piratages sont nécessaires mais nous pouvons le faire avec COMME , PATINDEX , GAUCHE ET DROITE et bonne concaténation des anciennes chaînes.

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

Mieux, il s'agit d'une version indépendante de SQL Server qui devrait fonctionner correctement.

16
Jorge Ferreira

Je pense que cela peut être fait beaucoup plus propre si vous utilisez différents STUFF :)

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
10
leoinfo

Que diriez-vous:

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

Éditer:

Je viens de réaliser que cela ignorera les colonnes avec partiellement correct &lt; chaînes.

Dans ce cas, vous pouvez ignorer la deuxième partie de la clause where et l'appeler ensuite:

    UPDATE tableName
    SET columName = REPLACE(columName , '&lt;;', '&lt;')
6
ilitirit

Cet article explique comment créer une fonction de remplacement de regex simple que vous pouvez utiliser dans SQL 2000 (et 2005 avec Tweak simple) qui peut vous aider.

3
Dillie-O

Très spécifique à ce modèle, mais j'ai fait similaire à cela dans le passé:

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

exemple plus large (encoder des caractères qui peuvent être inappropriés dans un attribut 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
Kristen

Si l'arôme regex de MSSQL prend en charge l'anticipation négative, ce serait la bonne façon d'aborder cela.

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

va attraper toutes les instances de & lt qui ne sont pas suivies d'un ;; (même si elles ne sont suivies de rien, ce qui [^;] serait miss) et ne capture pas le caractère non -= suivant dans le match, éliminant le problème mentionné dans les commentaires sur la question d'origine de ce caractère perdu dans le remplacement.

Malheureusement, je n'utilise pas MSSQL, donc je n'ai aucune idée s'il prend en charge l'anticipation négative ou non ...

1
Dave Sherohman