如何修复“不正确的字符串值”错误?

insrf1ej  于 2021-06-18  发布在  Mysql
关注(0)|答案(21)|浏览(935)

在注意到一个应用程序由于不正确的字符串值错误而倾向于丢弃随机电子邮件之后,我还是切换了许多文本列以使用 utf8 列字符集和默认列collate( utf8_general_ci )让它接受他们。这修复了大多数错误,并使应用程序在遇到非拉丁电子邮件时也不再出现sql错误。
尽管如此,一些电子邮件仍然导致程序出现错误的字符串值错误: (Incorrect string value: '\xE4\xC5\xCC\xC9\xD3\xD8...' for column 'contents' at row 1) “内容”列是 MEDIUMTEXT 使用 utf8 列字符集和 utf8_general_ci 列比较。此列中没有可切换的标志。
请记住,除非绝对必要,否则我不想接触或查看应用程序源代码:
是什么导致了这个错误(是的,我知道邮件里都是随机垃圾,但我认为utf8是相当宽容的)
我该怎么修?
这样的修复有什么可能的影响?
我考虑过的一件事是切换到启用二进制标志的utf8varchar([一些大的数字]),但我对mysql相当陌生,不知道这样的修复是否有意义。

mkshixfv

mkshixfv1#

在我的例子中,首先我在我的网站上遇到了一个'???',然后我检查了mysql的字符集,现在是拉丁文的,所以我把它改成utf-8,然后我重新启动了我的项目,然后我和你遇到了同样的错误,然后我发现我忘了改数据库的字符集,改成utf-8,砰,成功了。

g52tjvyc

g52tjvyc2#

该错误意味着要么您的字符串编码不正确(例如,您试图将iso-8859-1编码字符串输入utf-8编码列),要么该列不支持您试图输入的数据。
实际上,后一个问题是由mysql utf-8实现引起的,该实现只支持unicode字符,在utf-8中表示时需要1-3个字节。当试图通过jdbc将utf-8插入mysql时,请参阅“不正确的字符串值”?详情。

zzwlnbp8

zzwlnbp83#

mysql的utf-8类型实际上并不是合适的utf-8——它每个字符最多只使用3个字节,并且只支持基本的多语言平面(即没有emoji、没有astral平面等)。
如果需要存储来自更高unicode平面的值,则需要utf8mb4编码。

ttp71kqs

ttp71kqs4#

首先检查您的默认字符集名称是否为utf8。

SELECT default_character_set_name FROM information_schema.SCHEMATA S WHERE schema_name = "DBNAME";

如果结果不是utf8,则必须转换数据库。首先你必须保存一个垃圾场。
要将指定数据库中所有表的字符集编码更改为utf-8,请在命令行中键入以下命令。将dbname替换为数据库名称:

mysql --database=DBNAME -B -N -e "SHOW TABLES" | awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' | mysql --database=DBNAME

要将数据库本身的字符集编码更改为utf-8,请在mysql>提示符处键入以下命令。将dbname替换为数据库名称:

ALTER DATABASE DBNAME CHARACTER SET utf8 COLLATE utf8_general_ci;

现在可以尝试将utf8字符写入数据库。当我试图上传200000行csv文件到我的数据库时,这个解决方案对我很有帮助。

pod7payv

pod7payv5#

我几乎试过这里提到的每一步。都没用。下载的m

ubbxdtey

ubbxdtey6#

表和字段的编码错误;但是,您可以将它们转换为utf-8。

ALTER TABLE logtest CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE logtest DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE logtest CHANGE title title VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci;
j5fpnvbx

j5fpnvbx7#

我在列名之前添加了binary并解决了字符集错误。
插入表A值(二进制stringcolname1);

dhxwm5r4

dhxwm5r48#

如果在保存之前碰巧用某个字符串函数处理该值,请确保该函数可以正确处理多字节字符。如果字符串函数不能做到这一点,并且正在尝试截断,则可能会在中间拆分一个多字节字符,这可能会导致此类字符串错误情况。
例如,在php中,您需要从 substrmb_substr .

py49o6xq

py49o6xq9#

我已经尝试了以上所有的解决方案(都带来了有效的点),但没有任何工作为我。
直到我发现我在c中的mysql表字段Map使用了不正确的类型:mysqldbtype.blob。我把它改成mysqldbtype.text,现在我可以写所有我想要的utf8符号了!
p、 我的mysql表字段是“longtext”类型。但是,当我使用mygeneration软件自动生成字段Map时,它会自动将字段类型设置为c#中的mysqldbtype.blob。
有趣的是,我使用mysqldbtype.blob类型和utf8字符已经有好几个月没有问题了,直到有一天我试着写一个包含一些特定字符的字符串。
希望这能帮助那些正在努力寻找错误原因的人。

ercv8c1e

ercv8c1e10#

尽管您的排序规则设置为utf8\u general\u ci,但我怀疑数据库、表甚至列的字符编码可能不同。

ALTER TABLE tabale_name MODIFY COLUMN column_name VARCHAR(255)  
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
py49o6xq

py49o6xq11#

我也犯了类似的错误( Incorrect string value: '\xD0\xBE\xDO\xB2. ...' for 'content' at row 1 ). 我已尝试将列的字符集更改为 utf8mb4 之后,错误变为 'Data too long for column 'content' at row 1' .
结果发现mysql显示了错误的错误。我将列的字符集返回到 utf8 并将列的类型更改为 MEDIUMTEXT . 在那之后,错误消失了。
我希望它能帮助别人。
顺便说一下,mariadb在同样的情况下(我测试了相同的插入),只是剪切一个文本没有错误。

cigdeys3

cigdeys312#

这里有很好的答案。我只是添加了我的,因为我遇到了相同的错误,但结果是一个完全不同的问题(也许表面上是一样的,但根本原因不同。)
对我来说,以下字段发生了错误:

@Column(nullable = false, columnDefinition = "VARCHAR(255)")
private URI consulUri;

它最终以二进制序列化的形式存储在数据库中 URI 班级。这并没有引起单元测试(使用h2)或ci/集成测试(使用mariadb4j)的任何问题,它在我们的产品设置中失败了(不过,一旦理解了问题,就很容易在mariadb4j示例中看到错误的值;解决方案是构建一个自定义类型Map器:

package redacted;

import javax.persistence.AttributeConverter;
import java.net.URI;
import java.net.URISyntaxException;

import static java.lang.String.format;

public class UriConverter implements AttributeConverter<URI, String> {
    @Override
    public String convertToDatabaseColumn(URI attribute) {
        return attribute.toString();
    }

    @Override
    public URI convertToEntityAttribute(String field) {
        try {
            return new URI(field);
        }
        catch (URISyntaxException e) {
            throw new RuntimeException(format("could not convert database field to URI: %s", field));
        }
    }
}

使用方法如下:

@Column(nullable = false, columnDefinition = "VARCHAR(255)")
@Convert(converter = UriConverter.class)
private URI consulUri;

就hibernate而言,它似乎提供了一堆类型Map器,包括 java.net.URL ,但不是为了 java.net.URI (这正是我们需要的)。

afdcj2ne

afdcj2ne13#

嗨,我也有这个错误,当我使用我的在线数据库从godaddy服务器我认为它有5.1或更高版本的mysql。但是当我从localhost服务器(版本5.7)创建表并使用mysql-yog复制到在线服务器之后就没事了,我认为问题出在字符集上
此处截图

moiiocjp

moiiocjp14#

就我而言, Incorrect string value: '\xCC\x88'... ,问题是o-umlaut处于分解状态。这个问题和答案帮助我理解了 以及 ö . 在php中,我的解决方案是使用php的normalizer库。例如。, Normalizer::normalize('o¨', Normalizer::FORM_C) .

rxztt3cl

rxztt3cl15#

"\xE4\xC5\xCC\xC9\xD3\xD8" 不是有效的utf-8。使用python测试:

>>> "\xE4\xC5\xCC\xC9\xD3\xD8".decode("utf-8")
...
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

如果您正在寻找一种方法来避免数据库中的解码错误,那么cp1252编码(又名“windows-1252”又名“windows西欧”)是最允许的编码,每个字节值都是一个有效的码位。
当然,它不会再理解真正的utf-8,也不会理解任何其他非cp1252编码,但听起来你不太关心这个?

相关问题