online - MySQL REPLACE afecta a 0 filas pero WHERE... LIKE returns 90
phpmyadmin online (8)
¿Puedes intentar usar JOIN como se muestra a continuación?
UPDATE le_wp_posts l
INNER JOIN (SELECT t.post_content
FROM le_wp_posts t
WHERE t.post_content LIKE ''%Â%'') t ON l.post_content = t.post_content
SET l.post_content = REPLACE(l.post_content, ''Â'', '''')
Por alguna razón, al usar PhpMyAdmin se devuelven 90 filas cuando se ejecuta:
SELECT COUNT(*)
FROM le_wp_posts
WHERE post_content LIKE ''%Â%''
Pero las siguientes actualizaciones solo 3 filas:
UPDATE le_wp_posts
SET post_content = REPLACE(post_content, ''Â'', '''')
WHERE post_content LIKE ''%Â%''
También lo intenté omitiendo la cláusula WHERE
en la instrucción UPDATE
. ¿Hay algún motivo obvio que ignore que está causando este problema? ¿O qué pasos puedo seguir para investigar la causa? Mi SQL no es el mejor.
Hice la siguiente prueba ...
1) Crea una tabla con algunos datos:
create table test(col varchar(10));
insert into test values (''abc''), (''dbe'');
2) Seleccione el número de filas usando su mismo filtro (pero diferente carácter):
select count(*)
from test
where col like ''%B%'' -- note the uppercase
;
Obtuve el siguiente resultado:
+----------+ | count(*) | +----------+ | 2 | +----------+ 1 row in set
3) Intentó su actualización:
update test
set col = replace(col, ''B'', '''') -- note the uppercase
where col like ''%B%'' -- note the uppercase
;
Y obtuve este resultado:
Query OK, 0 rows affected (0.01 sec) Rows matched: 2 Changed: 0 Warnings: 0
En mi caso, un conjunto de caracteres predeterminado y una intercalación fueron utilizados en la creación de tablas. El conjunto de caracteres predeterminado era ''latin1'' y la intercalación ''latin1_swedish_ci''. Tenga en cuenta la ci
al final de la colación ... significa que no distingue entre mayúsculas y minúsculas . Entonces, el filtro LIKE
hizo una búsqueda insensible a mayúsculas, encontró 2 filas, pero la función REPLACE
, como se puede ver en la documentación, distingue entre mayúsculas y minúsculas . Probablemente, como en mi caso, la actualización encontró el mismo número de filas que en la selección, pero actualizó menos datos debido a la restricción del caso en REPLACE
.
Si este es su problema, ¿no puede simplemente ejecutar dos actualizaciones, una para mayúsculas y otra para minúsculas? Trataré de desarrollar una solución en una actualización ...
Los documentos sobre la función REPLACE(str, from_str, to_str)
:
Devuelve la cadena str con todas las ocurrencias de la cadena from_str reemplazada por la cadena to_str. REPLACE () realiza una coincidencia de mayúsculas y minúsculas al buscar from_str.
Los documentos sobre el operador LIKE
:
Las dos sentencias siguientes ilustran que las comparaciones de cadenas no distinguen entre mayúsculas y minúsculas, a menos que uno de los operandos distinga entre mayúsculas y minúsculas (utiliza una intercalación sensible a mayúsculas y minúsculas o es una cadena binaria):
El primer ejemplo:
mysql> SELECT ''abc'' LIKE ''ABC''; -> 1
El segundo ejemplo:
mysql> SELECT ''abc'' LIKE _latin1 ''ABC'' COLLATE latin1_general_cs; -> 0
Tenga en cuenta el cs
al final de la colación. Significa distinción de mayúsculas
Si tiene una "Id", podría intentarlo de esta manera:
UPDATE le_wp_posts
SET post_content = REPLACE(post_content, ''Â'', '''')
WHERE Id IN ( SELECT *
FROM (
SELECT Id
FROM le_wp_posts
WHERE post_content LIKE ''%Â%''
) as A
)
El LIKE no distingue entre mayúsculas y minúsculas, pero Replace es sensible a mayúsculas y minúsculas, para eludir el uso de la siguiente consulta:
UPDATE le_wp_posts
SET post_content = REPLACE(LOWER(post_content), LOWER(''Â''), '''')
WHERE post_content LIKE ''%Â%''
O si desea que el resultado final no sea minúsculas:
UPDATE le_wp_posts
SET post_content = REPLACE(REPLACE(post_content, LOWER(''Â''), ''''), ''Â'', '''')
WHERE post_content LIKE ''%Â%''
Supongo que la actualización no ocurrió desde PhpMyAdmin sino desde un cliente. Si es así, es solo la configuración regional diferente.
--Query first selects original column as well as replacement string and then update original column
Update Tbl1
Set Tbl1.post_content=Tbl2.Replacement
From le_wp_posts as Tbl1
Inner Join
(
select post_content,REPLACE(post_content,''Â'','''') as Replacement
from le_wp_posts
where post_content like ''%Â%''
) as Tbl2
On Tbl1.post_content=Tbl2.post_content
--you just need to put N before string pattern too (if you want look for unicode char)*/
Update le_wp_posts
Set post_content=REPLACE(post_content,N''Â'','''')
where post_content like ''%Â%''
Si toma un £ codificado en C2A3
( C2A3
, tratado como utf8) y lo almacena en una columna latin1, cuando lo lee de nuevo, obtiene £
( C2A3
, tratado como latin1). Eliminar el Â
funcionará para aproximadamente 32 caracteres, pero fallará para muchos otros caracteres. ¡Y hará que la mesa sea más difícil de reparar!
Veamos un ejemplo de lo que trataste de almacenar, junto con el HEX
de eso terminó en la mesa. Además, veamos SHOW CREATE TABLE
para confirmar mi sospecha de que el objetivo sea latin1
.
Esto discute la técnica de depuración HEX
. Y discute la "Mejor práctica", que incluye declarar, durante la conexión, que realmente tienes utf8, no latin1. Y habla de "Mojibake", con un ejemplo de dónde ñ
convierte en ñ
, lo que hace REPLACE
una perspectiva desordenada.
Su síntoma con LIKE
es consistente con los conjuntos de caracteres no coincidentes.