【问题标题】:MySQL REPLACE affects 0 rows but WHERE ... LIKE returns 90MySQL REPLACE 影响 0 行但 WHERE ... LIKE 返回 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 '%Â%') 的结果
  • 肮脏的解决方案: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 行已更新。我什至更改了连接器字符集以与服务器字符集相关联。我将尝试使用正则表达式替换

标签: mysql sql phpmyadmin


【解决方案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 行。这很奇怪
          • 已更新,请再次查看,感谢您报告问题
          • 错误:令牌不匹配现在:(
          猜你喜欢
          • 2019-05-05
          • 2021-05-06
          • 2016-01-19
          • 2015-04-15
          • 1970-01-01
          • 2016-02-01
          • 2013-07-08
          • 2013-02-17
          • 2015-02-22
          相关资源
          最近更新 更多