8字符故障;我看到的不是我储存的

uinbv5nw  于 2021-07-24  发布在  Java
关注(0)|答案(5)|浏览(396)

我试着用utf-8却遇到了麻烦。
我试过很多东西;以下是我得到的结果: ???? 而不是亚洲字符。即使是欧洲文本,我也有 Se?or 为了 Señor .
奇怪的胡言乱语(mojibake?),比如 Señor 或者 新浪新闻 为了 新浪新闻 .
黑钻石,如 selenium �或者。
最后,我遇到了数据丢失或至少被截断的情况: Se 为了 Señor .
即使我让文本看起来正确,它也没有正确排序。
我做错什么了?如何修复代码?我可以恢复数据吗?如果可以,如何恢复?

bjg7j2ky

bjg7j2ky1#

这个问题困扰着这个网站的参与者和其他许多人。
你列出了五个主要的 CHARACTER SET 麻烦。
最佳实践
展望未来,最好使用 CHARACTER SET utf8mb4 以及 COLLATION utf8mb4_unicode_520_ci . (管道中有更新版本的unicode排序规则。) utf8mb4 是的超集 utf8 因为它可以处理4字节的utf8代码,这是emoji和一些中文用户所需要的。
在mysql之外,“utf-8”表示所有大小的编码,因此实际上与mysql相同 utf8mb4 ,不是 utf8 .
下面我将尝试使用这些拼写和大写来区分mysql内部和外部。
概述你应该做什么
将编辑器等设置为utf-8。
html表单的开头应该是 <form accept-charset="UTF-8"> .
将字节编码为utf-8。
建立utf-8作为客户端使用的编码。
声明列/表 CHARACTER SET utf8mb4 (与核对) SHOW CREATE TABLE .) <meta charset=UTF-8> 在html的开头
存储例程获取当前字符集/排序规则。他们可能需要重建。
utf-8全程
有关计算机语言的更多详细信息(及其以下部分)
测试数据
使用工具或 SELECT 无法信任。太多这样的客户机,尤其是浏览器,试图补偿错误的编码,并向您显示正确的文本,即使数据库已损坏。所以,选择一个包含非英语文本的表和列,然后

SELECT col, HEX(col) FROM tbl WHERE ...

正确存储的utf-8的十六进制将是
对于空格(任何语言): 20 对于英语: 4x , 5x , 6x ,或 7x 对于大多数西欧国家来说,重音字母应该是 Cxyy 西里尔语、希伯来语和波斯语/阿拉伯语: Dxyy 亚洲大部分地区: Exyyzz 表情符号和一些中文: F0yyzzww 更多细节
出现问题的具体原因和解决方法
截断的文本( Se 为了 Señor ):
要存储的字节不编码为utf8mb4。修好这个。
另外,检查读取期间的连接是否为utf-8。
带问号的黑钻石( Se�or 为了 Señor ); 其中一种情况存在:
情况1(原始字节不是utf-8):
要存储的字节不编码为utf8。修好这个。
连接(或 SET NAMES )对于 INSERT 以及 SELECT 不是utf8/utf8mb4。修好这个。
另外,检查数据库中的列是否正确 CHARACTER SET utf8 (或utf8mb4)。
案例2(原始字节为utf-8):
连接(或 SET NAMES )对于 SELECT 不是utf8/utf8mb4。修好这个。
另外,检查数据库中的列是否正确 CHARACTER SET utf8 (或utf8mb4)。
只有当浏览器设置为 <meta charset=UTF-8> .
问号(普通的,不是黑钻石)( Se?or 为了 Señor ):
要存储的字节不编码为utf8/utf8mb4。修好这个。
数据库中的列无效 CHARACTER SET utf8 (或utf8mb4)。修好这个(使用 SHOW CREATE TABLE .)
另外,检查读取期间的连接是否为utf-8。
莫吉巴克( Señor 为了 Señor ):(这个讨论也适用于双重编码,它不一定是可见的。)
要存储的字节需要utf-8编码。修好这个。
连接在什么时候 INSERTing 以及 SELECTing 文本需要指定utf8或utf8mb4。修好这个。
该列需要声明 CHARACTER SET utf8 (或utf8mb4)。修好这个。
html应该以 <meta charset=UTF-8> .
如果数据看起来正确,但排序不正确,则可能是您选择了错误的排序规则,或者没有适合您需要的排序规则,或者您使用了双重编码。
双重编码可以通过执行 SELECT .. HEX .. 如上所述。

é should come back C3A9, but instead shows C383C2A9
The Emoji ? should come back F09F91BD, but comes back C3B0C5B8E28098C2BD

也就是说,十六进制大约是它应该的两倍长。这是由从latin1(或其他)转换为utf8引起的,然后将这些字节视为latin1并重复转换。排序(和比较)不能正常工作,因为它是排序,例如,字符串是 Señor .
尽可能修复数据
对于截断和问号,数据将丢失。
对于mojibake/双重编码。。。
对于黑钻石。。。
这里列出了修复程序(5种不同情况下的5种不同修复方法;仔细挑选):http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases

w80xi6nr

w80xi6nr2#

在服务器迁移之后,我的两个项目也遇到了类似的问题。在搜索和尝试了很多解决方案之后,我发现了一个:

mysqli_set_charset($con,"utf8");

在添加这一行到我的配置文件后,一切都正常!
我为mysqli找到了这个解决方案https://www.w3schools.com/php/func_mysqli_set_charset.asp 当我想从html查询中解决insert时
祝你好运!

unguejic

unguejic3#

我也在寻找同样的问题,我花了将近1个月的时间找到了合适的解决方案。首先,您将必须更新您的数据库将所有最近的字符和排序规则utf8mb4或至少支持utf-8数据。
对于java:
在建立jdbc连接时,将此添加到连接url useucode=yes&characterencoding=utf-8作为参数,它就可以工作了。
对于python:
在查询数据库之前,请尝试在光标上强制执行此操作* cursor.execute('SET NAMES utf8mb4') cursor.execute("SET CHARACTER SET utf8mb4") cursor.execute("SET character_set_connection=utf8mb4") *
如果它不起作用,快乐地寻找正确的解决方案。

lrpiutwd

lrpiutwd4#

你回答自己问题的方式很有趣:)
将代码ide语言设置为utf8
添加到您收集数据表单的网页标题。
检查mysql表定义,如下所示:

CREATE TABLE your_table (
  ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8

如果您正在使用pdo,请确保

$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); 
$dbL = new PDO($pdo, $user, $pass, $options);

如果已经有一个大型数据库存在上述问题,可以尝试使用正确的字符集导出sidu,然后使用utf8重新导入。祝你好运

disbfnqx

disbfnqx5#

根据服务器的设置方式,您必须相应地更改编码。utf8从你所说的应该是最好的工作,但是如果你得到奇怪的字符,它可能会有帮助,如果你改变网页编码为ansi。当我建立一个php mysqli时,这对我很有帮助,这可能会帮助你理解更多https://superuser.com/questions/762473/ansi-to-utf-8-in-notepad

相关问题