简体   繁体   English

java.sql.SQLException: 不正确的字符串值:'\\xF0\\x9F\\x91\\xBD\\xF0\\x9F...'

[英]java.sql.SQLException: Incorrect string value: '\xF0\x9F\x91\xBD\xF0\x9F...'

I have the following string value: "walmart obama 👽💔"我有以下字符串值:“walmart obama 👽💔”

I am using MySQL and Java.我正在使用 MySQL 和 Java。

I am getting the following exception: `java.sql.SQLException: Incorrect string value: '\\xF0\\x9F\\x91\\xBD\\xF0\\x9F...'我收到以下异常:`java.sql.SQLException:字符串值不正确:'\\xF0\\x9F\\x91\\xBD\\xF0\\x9F...'

Here is the variable I am trying to insert into:这是我试图插入的变量:

var1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL`

My Java code that is trying to insert "walmart obama 👽💔" is a preparedStatement.我试图插入“walmart obama 👽💔”的 Java 代码是一个 PreparedStatement。 So I am using the setString() method.所以我使用setString()方法。

It looks like the problem is the encoding of the values 👽💔.看起来问题是值的编码👽💔。 How can I fix this?我怎样才能解决这个问题? Previously I was using Derby SQL and the values 👽💔 just ended up being two sqaures (I think this is the representation of the null character)以前我使用的是 Derby SQL 并且值 👽💔 最终是两个平方(我认为这是空字符的表示)

All help is greatly appreciated!非常感谢所有帮助!

What you have is EXTRATERRESTRIAL ALIEN (U+1F47D) and BROKEN HEART (U+1F494) which are not in the basic multilingual plane.您拥有的是EXTRATERRESTRIAL ALIEN (U+1F47D)BROKEN HEART (U+1F494) ,它们不在基本的多语言平面中。 They cannot be even represented in java as one char, "👽💔".length() == 4 .它们甚至不能在 java 中表示为一个字符, "👽💔".length() == 4 They are definitely not null characters and one will see squares if you are not using fonts that support them.它们绝对不是空字符,如果您不使用支持它们的字体,则会看到正方形。

MySQL's utf8 only supports basic multilingual plane, and you need to use utf8mb4 instead : MySQL 的utf8只支持基本的多语言平面,需要使用utf8mb4代替

For a supplementary character, utf8 cannot store the character at all, while utf8mb4 requires four bytes to store it.对于补充字符,utf8 根本无法存储该字符,而 utf8mb4 需要四个字节来存储它。 Since utf8 cannot store the character at all, you do not have any supplementary characters in utf8 columns and you need not worry about converting characters or losing data when upgrading utf8 data from older versions of MySQL.由于 utf8 根本无法存储字符,因此您在 utf8 列中没有任何补充字符,并且您无需担心在从旧版本的 MySQL 升级 utf8 数据时转换字符或丢失数据。

So to support these characters, your MySQL needs to be 5.5+ and you need to use utf8mb4 everywhere.所以为了支持这些字符,你的 MySQL 需要是 5.5+ 并且你需要在utf8mb4地方使用utf8mb4 Connection encoding needs to be utf8mb4 , character set needs to be utf8mb4 and collaction needs to be utf8mb4 .连接编码需要是utf8mb4 ,字符集需要是utf8mb4 ,排序需要是utf8mb4 For java it's still just "utf-8" , but MySQL needs a distinction.对于 Java,它仍然只是"utf-8" ,但 MySQL 需要区分。

I don't know what driver you are using but a driver agnostic way to set connection charset is to send the query:我不知道您使用的是什么驱动程序,但与驱动程序无关的设置连接字符集的方法是发送查询:

SET NAMES 'utf8mb4'

Right after making the connection.建立连接后。

See also this for Connector/J : 另请参阅 Connector/J

14.14: How can I use 4-byte UTF8, utf8mb4 with Connector/J? 14.14: 我怎样才能在 Connector/J 中使用 4 字节的 UTF8、utf8mb4?

To use 4-byte UTF8 with Connector/J configure the MySQL server with character_set_server=utf8mb4.要将 4 字节 UTF8 与 Connector/J 一起使用,请使用 character_set_server=utf8mb4 配置 MySQL 服务器。 Connector/J will then use that setting as long as characterEncoding has not been set in the connection string .然后连接器/ J将使用该设置,只要和characterEncoding尚未连接字符串中设置 This is equivalent to autodetection of the character set.这相当于字符集的自动检测。

Adjust your columns and database as well:还要调整您的列和数据库:

var1 varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL

Again, your MySQL version needs to be relatively up-to-date for utf8mb4 support.同样,您的 MySQL 版本需要相对最新才能支持 utf8mb4。

Weirdly, I found that REMOVING &characterEncoding=UTF-8 from the JDBC url did the trick for me with similar issues.奇怪的是,我发现 REMOVING &characterEncoding=UTF-8 from the JDBC url为我解决了类似的问题。

Based on my properties,根据我的属性,

jdbc_url=jdbc:mysql://localhost:3306/dbName?useUnicode=true

I think this supports what @Esailija has said above, ie my MySQL, which is indeed 5.5, is figuring out its own favorite flavor of UTF-8 encoding.我认为这支持@Esalija 上面所说的,即我的 MySQL,它确实是 5.5,正在弄清楚它自己最喜欢的 UTF-8 编码风格。

(Note, I'm also specifying the InputStream I'm reading from as UTF-8 in the java code, which probably doesn't hurt)... (请注意,我还在 java 代码中将我正在读取的InputStream指定为UTF-8 ,这可能不会造成伤害)...

All in all, to save symbols that require 4 bytes you need to update characher-set and collation for utf8mb4 :总而言之,要保存需要 4 个字节的符号,您需要更新 utf8mb4 的字符集和排序utf8mb4

  1. database table/column: alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci数据库表/列: alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci
  2. database server connection ( see )数据库服务器连接(请参阅

On my development enviromnt for #2 I prefer to set parameters on command line when starting the server: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci在我的 #2 开发环境中,我更喜欢在启动服务器时在命令行上设置参数: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci


btw, pay attention to Connector/J behavior with SET NAMES 'utf8mb4' :顺便说一句,注意使用SET NAMES 'utf8mb4' Connector/J 行为

Do not issue the query set names with Connector/J, as the driver will not detect that the character set has changed, and will continue to use the character set detected during the initial connection setup.不要使用 Connector/J 发出查询集名称,因为驱动程序不会检测到字符集已更改,并将继续使用在初始连接设置期间检测到的字符集。

And avoid setting characterEncoding parameter in connection url as it will override configured server encoding:并避免在连接 url 中设置characterEncoding参数,因为它会覆盖配置的服务器编码:

To override the automatically detected encoding on the client side, use the characterEncoding property in the URL used to connect to the server.要覆盖客户端自动检测到的编码,请使用用于连接到服务器的 URL 中的 characterEncoding 属性。

How I solved my problem.我是如何解决我的问题的。

I had我有

?useUnicode=true&amp;characterEncoding=UTF-8

In my hibernate jdbc connection url and I changed the string datatype to longtext in database, which was varchar before.在我的 hibernate jdbc 连接 url 中,我将数据库中的字符串数据类型更改为 longtext,之前是 varchar。

我遇到了同样的问题,并通过将每列的排序规则设置为utf8_general_ci来解决它。

Append the line useUnicode=true&amp;characterEncoding=UTF-8 to your jdbc url.useUnicode=true&amp;characterEncoding=UTF-8行附加到您的 jdbc url。

In your case the data is not being send using UTF-8 encoding.在您的情况下,数据不是使用UTF-8编码发送的。

I guess MySQL doesn't believe this to be valid UTF8 text.我猜 MySQL 不相信这是有效的 UTF8 文本。 I tried an insert on a test table with the same column definition (mysql client connection was also UTF8) and although it did the insert, the data I retrieved with the MySQL CLI client as well as JDBC didn't retrieve the values correctly.我尝试在具有相同列定义的测试表上插入(mysql 客户端连接也是 UTF8),尽管它进行了插入,但我使用 MySQL CLI 客户端和 JDBC 检索的数据没有正确检索值。 To be sure UTF8 did work correctly, I inserted an "ö" instead of an "o" for obama:为了确保 UTF8 正常工作,我为 obama 插入了一个“ö”而不是“o”:

johan@maiden:~$ mysql -vvv test < insert.sql 
--------------
insert into utf8_test values(_utf8 "walmart öbama 👽💔")
--------------

Query OK, 1 row affected, 1 warning (0.12 sec)

johan@maiden:~$ file insert.sql 
insert.sql: UTF-8 Unicode text

Small java application to test with:用于测试的小型 Java 应用程序:

package test.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test
{

    public static void main(String[] args)
    {
        System.out.println("test string=" + "walmart öbama 👽💔");
        String url = "jdbc:mysql://hostname/test?useUnicode=true&characterEncoding=UTF-8";
        try
        {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection c = DriverManager.getConnection(url, "username", "password");
            PreparedStatement p = c.prepareStatement("select * from utf8_test");
            p.execute();
            ResultSet rs = p.getResultSet();
            while (!rs.isLast())
            {
                rs.next();
                String retrieved = rs.getString(1);
                System.out.println("retrieved=\"" + retrieved + "\"");

            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

}

Output:输出:

johan@appel:~/workspaces/java/javatest/bin$ java test.sql.Test
test string=walmart öbama 👽💔
retrieved="walmart öbama "

Also, I've tried the same insert with the JDBC connection and it threw the same exception you are getting.此外,我已经尝试使用 JDBC 连接进行相同的插入操作,但它抛出了您遇到的相同异常。 I believe this to be a MySQL bug.我相信这是一个 MySQL 错误。 Maybe there's a bug report about such a situation already..也许已经有关于这种情况的错误报告了..

我遇到了同样的问题,在仔细检查所有字符集并发现它们都没有问题后,我意识到我在班级中的被窃听的属性被注释为 @Column 而不是 @JoinColumn (javax.presistence; hibernate) 和它打破了一切。

execute执行

show VARIABLES like "%char%”;

find character-set-server if is not utf8mb4.如果不是 utf8mb4,则查找字符集服务器。

set it in your my.cnf, like将其设置在您的 my.cnf 中,例如

vim /etc/my.cnf

add one line添加一行

character_set_server = utf8mb4

at last restart mysql最后重启mysql

This setting useOldUTF8Behavior=true worked fine for me.这个设置 useOldUTF8Behavior=true 对我来说很好用。 It gave no incorrect string errors but it converted special characters like à into multiple characters and saved in the database.它没有给出不正确的字符串错误,但它将特殊字符如 à 转换为多个字符并保存在数据库中。

To avoid such situations, I removed this property from the JDBC parameter and instead converted the datatype of my column to BLOB.为了避免这种情况,我从 JDBC 参数中删除了这个属性,而是将我的列的数据类型转换为 BLOB。 This worked perfect.这很完美。

此外,数据类型可以使用 varchar 或 text 的 blob 安装。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 异常java.sql.SQLException:错误的字符串值:&#39;Rins&#39;列第1行的&#39;\\ xF0 \\ x9F \\ x92 \\ xBC&#39; - Exception java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\xBC' for column 'Rins' at row 1 at java.sql.SQLException:字符串值不正确:&#39;\\ xF0 \\ x9F \\ x98 \\ x8F&#39;表示第1行的&#39;tweetcontent&#39;列 - java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8F' for column 'tweetcontent' at row 1 使用 hibernate 将表情符号保存到 mysql 字符串值不正确:'\xF0\x9F\x98\x88\xF0\x9F...' 用于第 1 行的列“名称” - saving emoji to mysql using hibernate Incorrect string value: '\xF0\x9F\x98\x88\xF0\x9F…' for column 'name' at row 1 已经在使用 utf8mb4 但得到 1366: Incorrect string value: &#39;\\xF0\\x9F\\x98\\x81\\xF0\\x9F...&#39; - Already using utf8mb4 but getting 1366: Incorrect string value: '\xF0\x9F\x98\x81\xF0\x9F…' 字符串值不正确:&#39;\\ xF0 \\ x9F \\ xA4 \\ x96 - Incorrect string value: '\xF0\x9F\xA4\x96<b…' for column 'body' at row 1 java.sql.SQLException:字符串值不正确:&#39;\\ xF3 \\ xBE \\ x8D \\ x81&#39; - java.sql.SQLException: Incorrect string value: '\xF3\xBE\x8D\x81' 字符编码:java.sql.SQLException:不正确的字符串值:列的&#39;\\ xF5fi S \\ xE1…&#39; - Character encoding: java.sql.SQLException: Incorrect string value: '\xF5fi S\xE1…' for column java.sql.SQLException:不正确的字符串值:'\xAC\xED\x00\x05sr...' - java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' Spring Boot and Mysql: Caused by: java.sql.SQLException: Incorrect string value: '\x96 like...' for column 'description' at row 1 - Spring Boot and Mysql : Caused by: java.sql.SQLException: Incorrect string value: '\x96 like...' for column 'description' at row 1 将 mysql 5.5.62 数据库架构迁移到 mysql 8.0.27 - 偶发错误 java.sql.SQLException:字符串值不正确:列的“\\xE2\\x80\\x8B” - migrating mysql 5.5.62 database schema to mysql 8.0.27 - sporadic error java.sql.SQLException: Incorrect string value: '\xE2\x80\x8B' for column
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM