MySQL REPLACE 影响 0 行但 WHERE ... LIKE 返回 90
Posted
技术标签:
【中文标题】MySQL REPLACE 影响 0 行但 WHERE ... LIKE 返回 90【英文标题】:MySQL REPLACE affects 0 rows but WHERE ... LIKE returns 90 【发布时间】:2017-01-27 17:13:23 【问题描述】:由于某种原因,使用 phpMyAdmin 在运行时返回 90 行:
SELECT COUNT(*)
FROM le_wp_posts
WHERE post_content LIKE '%Â%'
但以下仅更新 3 行:
UPDATE le_wp_posts
SET post_content = REPLACE(post_content, 'Â', '')
WHERE post_content LIKE '%Â%'
我也尝试过在UPDATE
语句中省略WHERE
子句。我忽略了导致此问题的任何明显原因吗?或者我可以采取哪些步骤来进一步调查原因?我的 SQL 不是最好的。
【问题讨论】:
您是否尝试在 where 条件中使用 select 子句:WHERE post_content IN (SELECT distinct post_content FROM le_wp_posts WHERE post_content LIKE '%Â%')
@pat #1093 - You can't specify target table 'le_wp_posts' for update in FROM clause
是 UPDATE le_wp_posts SET post_content = REPLACE(post_content, 'Â', '') WHERE post_content IN (SELECT distinct post_content FROM le_wp_posts WHERE post_content LIKE '%Â%')
的结果
***.com/questions/45494/… - 看看这个
肮脏的解决方案:UPDATE le_wp_posts SET post_content = REPLACE(post_content, 'Â', '') WHERE post_content IN (SELECT distinct post_content FROM (select * from le_wp_posts) as x WHERE post_content LIKE '%Â% ')
@Pat 谢谢,在您发帖时正在查看。返回 0 行已更新。我什至更改了连接器字符集以与服务器字符集相关联。我将尝试使用正则表达式替换
【参考方案1】:
--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 '%Â%'
【讨论】:
【参考方案2】:--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
【讨论】:
【参考方案3】:我猜更新不是来自 PhpMyAdmin 内部而是来自客户端? 如果是这样,那只是区域设置不同。
【讨论】:
【参考方案4】:如果你将一个 utf8 编码的£
(C2A3
,视为 utf8)存储到一个 latin1 列中,当你读回它时,你会得到 £
(C2A3
,视为 latin1) .删除 Â
将适用于大约 32 个字符,但对于许多其他字符将失败。 而且它会使桌子更难修复!
让我们看一个示例,说明您尝试存储的内容以及表格中最终出现的HEX
。另外,让我们看一下SHOW CREATE TABLE
,以确认我的怀疑目标是latin1
。
This 讨论了HEX
调试技术。它讨论了“最佳实践”,其中包括在连接期间声明您确实拥有 utf8,而不是 latin1。它还谈到了“Mojibake”,并举例说明了ñ
变成ñ
,使REPLACE
变得混乱。
LIKE
的症状与字符集不匹配一致。
【讨论】:
【参考方案5】:LIKE 不区分大小写,但 Replace 区分大小写,要绕过它,请使用以下查询:
UPDATE le_wp_posts
SET post_content = REPLACE(LOWER(post_content), LOWER('Â'), '')
WHERE post_content LIKE '%Â%'
或者,如果您希望最终结果不是小写:
UPDATE le_wp_posts
SET post_content = REPLACE(REPLACE(post_content, LOWER('Â'), ''), 'Â', '')
WHERE post_content LIKE '%Â%'
【讨论】:
不区分大小写取决于列的排序规则。LIKE
区分大小写或不区分大小写,具体取决于排序规则。 (我在反驳你的第一句话。)在我的回答中,我认为LIKE
与真正的问题和解决方案 没有任何关系。【参考方案6】:
我做了以下测试...
1) 创建一个包含一些数据的表:
create table test(col varchar(10));
insert into test values ('abc'), ('dbe');
2) 使用相同的过滤器(但字符不同)选择行数:
select count(*)
from test
where col like '%B%' -- note the uppercase
;
得到以下结果:
+----------+ |计数(*) | +----------+ | 2 | +----------+ 1排成套3) 尝试了您的更新:
update test
set col = replace(col, 'B', '') -- note the uppercase
where col like '%B%' -- note the uppercase
;
得到了这个结果:
查询正常,0 行受影响(0.01 秒) 匹配行:2 已更改:0 警告:0在我的例子中,创建表时使用的默认字符集和排序规则。默认字符集是“latin1”和排序规则“latin1_swedish_ci”。请注意排序规则末尾的ci
....表示不区分大小写。因此,LIKE
过滤器进行了不区分大小写的搜索,找到了 2 行,但 REPLACE
函数(如文档中所示)区分大小写。可能与我的情况一样,更新发现的行数与选择中的行数相同,但由于REPLACE
的大小写限制,更新的数据较少。
如果这是您的问题,您不能只运行两个更新,一个用于大写字母,一个用于小写字母吗?我将尝试在一次更新中开发解决方案...
关于REPLACE(str, from_str, to_str)
函数的docs:
返回字符串 str,其中所有出现的字符串 from_str 都替换为字符串 to_str。 REPLACE() 在搜索 from_str 时执行区分大小写的匹配。
docs 关于LIKE
运算符:
以下两个语句说明字符串比较不区分大小写,除非其中一个操作数区分大小写(使用区分大小写的排序规则或二进制字符串):
第一个例子:
mysql> SELECT 'abc' LIKE 'ABC'; -> 1第二个例子:
mysql> SELECT 'abc' LIKE _latin1 'ABC' COLLATE latin1_general_cs; -> 0注意排序规则末尾的cs
。这意味着区分大小写。
【讨论】:
"如果这是您的问题,您不能只运行两个更新,一个用于大写字母,一个用于小写字母吗?"可能适用于一个字符,但长字符串的标题大小写呢?【参考方案7】:如果你有一个“Id”,你可以试试这个方法:
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
)
【讨论】:
您可能不需要在IN
子句中使用SELECT *
进行另一个子选择。
sql fiddle 运行没有错误。不同的版本还是什么?我很好奇。
@KamilG。我在 XAMPP 版本上使用 Mysql 版本 5.6.24:5.6.8 和 PhpMyAdmin 4.5.4.1
这里只播放 MySQL 版本。尝试控制台看看它不会产生错误。
@KamilG。仅当您引用同一个表时才会发生错误。你的小提琴引用了一个不同的表。此外,您需要进行删除或更新才能看到这一点。【参考方案8】:
请您尝试使用以下 JOIN:
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, 'Â', '')
【讨论】:
好的,因为a
不是表,所以查询中出现错误,所以我将a.post_content
更改为l.post_content
,如下所示: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(t.post_content, 'Â', '')
但是再次影响了 0 行。这很奇怪
已更新,请再次查看,感谢您报告问题
错误:令牌不匹配现在:(以上是关于MySQL REPLACE 影响 0 行但 WHERE ... LIKE 返回 90的主要内容,如果未能解决你的问题,请参考以下文章