【问题标题】:replace garbage characters within mysql替换mysql中的垃圾字符
【发布时间】:2012-02-13 21:55:06
【问题描述】:

我的数据库位于 latin1 中,并且充满了 â"'��"'(取决于我的终端分别设置为 latin1 还是 unicode)。从上下文来看,我认为它们应该是 emdashes。在 IE 中呈现(或不呈现)时,它们似乎会导致令人讨厌的错误。我想找到并替换它们。问题是 â 和 � 字符都不匹配 replace。运行查询:

    update TABLE set COLUMN = replace(COLUMN,'��"','---');

执行没有错误,但不执行任何操作(更改了 0 行)。我很清楚,当我在终端中复制“菱形中的问号”字符时,它不匹配。有没有办法找出它的代码并与之匹配? mysql 控制台非常接近能够在一行中执行此操作,因此如果可以避免的话,我宁愿不在终端之外编写脚本。

数据库托管在 Amazon RDS 上,因此我无法安装我在此处的其他问题中看到的正则表达式 udf。从长远来看,我将不得不将整个 db 正确转换为 utf8,但我需要立即解决此渲染问题。

编辑:

我已经用hexdump 隔离了坏字符,它是 e2 80(我认为这不对应于任何 unicode 字符)。如何将其提供给替换功能?

    update TABLE set COLUMN = replace(COLUMN, char(0xe2,0x80),'---');

什么都不做。

【问题讨论】:

  • 有理由让它成为 latin1 吗?我现在倾向于默认使用 unicode,而且转换起来并不难 - 只需将数据库转储到 SQL,然后将其重新加载到使用 utf8 的新数据库中。
  • 我继承了它。转储是不可取的,因为它会导致我想避免的大量停机时间。我一直在阅读诸如 nicj.net/2011/04/17/… 之类的就地方法,但还没有时间将其适应我的数据库。
  • 您可能别无选择,只能找到具有此错误字符序列的所有行并手工制作单独的语句来修复每个行(不过,脚本可以帮助做到这一点)。
  • 数据是存储不正确,显示不正确,还是真的坏了?请查看kunststube.net/frontback 的数据库部分并尝试弄清楚。答案可能是以“错误”编码导出数据,然后以正确编码重新导入。
  • 在这种特殊情况下,以上所有内容。通常,我们将好的 UTF8 存储在 latin1 列中,然后将其拉出并将其呈现为 UTF8,以便一切顺利进行。第二件事是不对的,虽然......它变得非常难以管理。我很快就会将数据库中的所有内容都转换为 UTF8。

标签: mysql character-encoding latin1


【解决方案1】:

我想通了。我使用 mysql 的内置 hex 函数转储了一个我知道不好的条目。

    select hex(column) from table where id=666;

然后挑选出单词(那些夹在“20”之间的数字)并发现我的违规字节集实际上是x'C3A2E282AC2671756F743B'。这与我在 PHP 和我的系统中看到的编码方式(如e2 80)是如何对应的,我不知道,在这一点上,我真的不在乎。

为了验证,在销毁数据之前,将其重新插入 mysql:

    select x'C3A2E282AC2671756F743B';
    +---------------------------+
    | x'C3A2E282AC2671756F743B' |
    +---------------------------+
    | â€"               |
    +---------------------------+
    1 row in set (0.00 sec)

因此,使用上面的替换查询,我能够一次删除所有不良数据。

记录在案:

    update TABLE set COLUMN = replace(COLUMN, x'C3A2E282AC2671756F743B','--');

我真的希望这对某人有用。虽然编码混乱在 mysql 中似乎很常见,但我到处搜索,但我找不到这个最终相当简单的过程的解释。

【讨论】:

  • x'C3A2'â 的 UTF-8; x'E282AC' 的 UTF-8; x'2671756F743B'" 的 ASCII,所以有些东西正在做 Unicode 编码...
  • @Neil 我认为故事是用一些 MS cp1252(或不同的 MS 方案??)准备文本,然后无效地转换为 UTF8 并转储到 latin1 列中。 cp1252 en/em dash 不能很好地复制到 UTF8,所以无论将它转换成什么似乎是任意的垃圾......但是 en(em)dash 在 cp1252 和 E2 80 93 (E2 80) 中是 96(97) 94) 在 UTF8 中...不知道其中任何一个如何变成 c3a2e82ac...
  • E2 80 94 在 Windows-1252 中是 — - 也许聪明的引用变成了 " 在某个地方。
【解决方案2】:

某些东西可能已经提交了带有 UTF-8 编码 (E2 80 94) 的破折号 (U+2014),您现在正试图将其解释为 latin-1,但是这在 latin-1 中无效,不包括范围为 80-9F,因此您可能会看到非法字节的 Unicode 替换字符,因此在显示时会导致 â��。相比之下,在 Windows-1252 中,它将显示为 —

您可以使用CHAR(0xE2, 0x80, 0x94) 创建搜索字符串。

【讨论】:

  • 您的回答使我朝着正确的方向前进,我发现坏字符是 e2 80 。但是如何形成替换查询?这不是我所期望的那样。
  • 其实……不是e2 80。下面看我解决问题的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多