将希伯来语字符插入 MySQL 表时获取问号

Posted

技术标签:

【中文标题】将希伯来语字符插入 MySQL 表时获取问号【英文标题】:Getting question marks when inserting Hebrew characters into a MySQL table 【发布时间】:2012-12-16 06:48:29 【问题描述】:

我正在使用 Netbeans 构建一个使用 Java、JSP 的 Web 应用程序,用于处理带有希伯来语字段的数据库。

DDL 如下:

String cityTable = "CREATE TABLE IF NOT EXISTS hebrew_test.table ("
                            +"id int(11) NOT NULL AUTO_INCREMENT,"
                            +"en varchar(30) NOT NULL,"
                            +"he varchar(30) COLLATE utf8_bin NOT NULL,"
                            +"PRIMARY KEY (id)"
                            +") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;";
String insert = "INSERT INTO hebrew_test.table (en, he) VALUES ('A','a')";
String insert2 = "INSERT INTO hebrew_test.table (en, he) VALUES ('B','ב')";
String insert3 = "INSERT INTO hebrew_test.table (en, he) VALUES ('C','אבג')";


executeSQLCommand(cityTable);
executeSQLCommand(insert);
executeSQLCommand(insert2);
executeSQLCommand(insert3);

我得到的输出表:

1   A   a
2   B   ?
3   C   ???

代替:

1   A   a
2   B   ב
3   C   אבג

我试过Hebrew appears as question marks in Netbeans,但这不是同一个问题。我得到了表格中的问号。

我也将表格定义为UTF8_bin,正如您在上面的代码中看到的那样。

【问题讨论】:

您使用的是什么数据库? (另外,它是“水管工”)。 我用的是SQL数据库,建db的代码:_statement.executeUpdate("CREATE DATABASE IF NOT EXISTS prodb"); 【参考方案1】:

您将值直接包含在 SQL 中。这总是是个坏主意。使用PreparedStatement,参数化SQL,并将值设置为参数。它可能不能解决问题——但这绝对是首先要尝试的事情,因为无论如何您都应该使用参数化 SQL。 (参数化SQL避免SQL injection attacks,将代码与数据分离,避免不必要的转换。)

接下来,您应该找出问题真正发生的确切位置:

确保您尝试插入的值正确。 检查您检索的值是否正确。 使用Wireshark 检查您的网络响应中的内容 - 检查声明的编码实际数据中的内容

检查值时,您应该遍历字符串中的每个字符并将值打印为 UTF-16 代码单元(使用 toCharArray() 或在循环中使用 charAt())。仅将值打印到控制台会留下太多其他问题的机会。

编辑:关于我为什么写这个作为答案的一点背景:

根据我的经验,将字符串值作为参数而不是直接写入 SQL 可以有时避免此类问题(出于安全原因等原因当然更好)。 根据我的经验,诊断问题出在数据库端还是 Web 端也很重要。最好通过记录所使用的确切 UTF-16 代码单元来完成此诊断,而不仅仅是字符串(否则在记录或控制台输出期间可能会出现进一步的编码问题)。 根据我的经验,在插入 读取代码路径时很容易出现此类问题。

作为推动 OP 前进的一种方式,所有这些都非常重要,而不仅仅是在类似评论的请求中提供更多信息。

【讨论】:

感谢 Jon 我发现:roseindia.net/jdbc/prepared-statement-example.shtml @MatanTouti:我不会说这是一个很棒的页面——糟糕的异常处理,没有资源清理等等......docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html 稍微好一些,虽然仍然不完美...... 调试器尝试插入的值是正确的(验证是否足够好?): allprofessions = "INSERT INTO prodb.professions (id,professional,professions) VALUES (1,'אחר ','其他'),(2,'חשמלאי','电工'),(3,'אינסטלטור','水管工')“。我实际得到的值是我上面显示的表格。以及如何检查网络响应超出了我的知识范围。我认为答案更像是某个地方的 UTF 8 声明(我猜)。 @MatanTouti:嗯,正如我所说的 - 使用 Wireshark 来查看响应中的确切内容。如果您以前没有使用过 Wireshark,那么现在是学习的好时机 - 所有 Web 开发人员都应该知道如何查看网络中的内容... 我正在运行的服务器是 localhost,带有 xampp。我可以使用wireshark来检查它虽然它的本地主机吗?【参考方案2】:

在将表示 SQL 查询的字符解码为字节时,您需要告诉 JDBC 驱动程序使用 UTF-8 编码。您可以通过将 useUnicode=yescharacterEncoding=UTF-8 查询参数添加到 JDBC 连接 URL 来实现。

jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8

否则它将使用操作系统平台默认字符集。 MySQL JDBC 驱动程序本身非常了解客户端(运行 JDBC 代码的位置)和服务器端(数据库表所在的位置)使用的编码。任何未被 DB 表使用的字符集覆盖的字符都将替换为问号。

另见:

Spring Encoding with CharacterEncodingFilter in web.xml

【讨论】:

你是最棒的,我的朋友!!!我一直在寻找解决方案很长时间。更改了几乎所有的字符集和排序规则:D 非常感谢!

以上是关于将希伯来语字符插入 MySQL 表时获取问号的主要内容,如果未能解决你的问题,请参考以下文章

如何将希伯来语值插入 php 中的 mysql 数据库

通过 PHP 将数据插入 MySQL 表时出错

部分中文插入mysql数据库变成问号,怎么回事

PHP插入MYSQL数据库中文变成乱码 问号

c# 操作mysql数据库的时候会出现 插入中文汉字变成问号?

当我将图像插入 MySQL 表时,结果为 NULL