Pregunta

¿Cuál es la mejor manera de reemplazar todos '& amp; lt' con & amp; lt; en una columna de base de datos dada? Básicamente realice s/&lt[^;font>/</gi

Notas:

  • debe funcionar en MS SQL Server 2000
  • Debe ser repetible (y no terminar con & amp; lt ;;;;;;;;;; )
¿Fue útil?

Solución

Se requiere algún pirateo, pero podemos hacerlo con LIKE , PATINDEX , LEFT AND RIGHT y good old concatenación de cadenas.

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

Mejor es que esta es una versión independiente de SQL Server y debería funcionar bien.

Otros consejos

Creo que esto se puede hacer mucho más limpio si usa COSAS diferentes :)

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

¿Qué tal:

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

Editar:

Me acabo de dar cuenta de que esto ignorará las columnas con cadenas & amp; lt; parcialmente correctas.

En ese caso, puede ignorar la segunda parte de la cláusula where y llamar a esto después:

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

Este artículo cubre cómo crear una función simple de reemplazo de expresiones regulares que puede usar en SQL 2000 (y 2005 con un simple ajuste) que pueda ayudarlo.

Si el sabor de expresión regular de MSSQL admite una búsqueda anticipada negativa, esa sería la forma correcta de abordar esto.

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

capturará todas las instancias de & amp; lt que no estén seguidas de un ; (incluso si no van seguidas de nada, lo que [^;] fallaría) y no captura el siguiente personaje que no sea ; como parte de la partida, eliminando el problema mencionado en los comentarios sobre la pregunta original de que ese personaje se perdió en el reemplazo.

Desafortunadamente, no uso MSSQL, así que no tengo idea de si es compatible con anticipación negativa o no ...

Muy específico para este patrón, pero he hecho algo similar en el pasado:

REPLACE (REPLACE (columnName, '& amp; lt;', '& amp; lt'), '& amp; lt', '& amp; lt;')

ejemplo más amplio (codificar caracteres que pueden ser inapropiados en un atributo 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')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top