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的主要内容,如果未能解决你的问题,请参考以下文章

mysql 处理数据库中的重复行

sql update操作结果

SSIS 包写入 0 行但仅运行 DataFlow 并获得 400k 行

mysql 索引

mysql 索引

是否可以隐藏 UITableView 的行但不能隐藏搜索栏?