Mysql2::Error: 不正确的字符串值

Posted

技术标签:

【中文标题】Mysql2::Error: 不正确的字符串值【英文标题】:Mysql2::Error: Incorrect string value 【发布时间】:2014-04-23 05:27:44 【问题描述】:

我有一个在生产模式下运行的 Rails 应用程序,但是今天当用户尝试保存记录时突然出现此错误。

mysql2::Error: Incorrect string value

更多细节(来自生产日志):

Parameters: "utf8"=>"â<9c><93>" ... 

Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k 

Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k 

现在我看到了一些需要删除数据库并重新创建它的解决方案,但我不能这样做。

现在mysql显示这个:

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.04 sec)

出了什么问题,我该如何更改它以使我对任何字符都没有任何问题?

另外:这个问题可以用 javascript 解决吗?在发送之前转换它?

谢谢

【问题讨论】:

Mysql - Mysql2::Error: Incorrect string value:的可能重复 另见:dev.mysql.com/doc/refman/5.5/en/… 【参考方案1】:

问题是由您的 mysql 服务器端的字符集引起的。您可以像这样手动配置:

ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8

或删除表并重新创建它:

rake db:drop
rake db:create
rake db:migrate

参考:

https://***.com/a/18498210/2034097

https://***.com/a/16934647/2034097

更新

第一个命令只影响指定的表,如果你想改变一个数据库中的所有表,你可以这样做

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;

参考:

https://***.com/a/6115705/2034097

【讨论】:

我对我的所有表运行此 ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8。 我的记录还在,我可以使用它们并创建新的。伟大的。现在如果我想创建其他表,我将不得不再次运行它,对吗? 恭喜,回答你的问题,我更新了我的答案,请看一下。 运行 ALTER DATABASE 命令并没有改变我的问题表的字符集。运行 ALTER TABLE 确实有效。我能够使用以下命令检查字符集名称。 SELECT CCSA.character_set_name FROM information_schema.TABLEST, information_schema.COLLATION_CHARACTER_SET_APPLICABILITY CCSA WHERE CCSA.collat​​ion_name = T.table_collat​​ion AND T.table_schema = "your_databasename" AND T.table_name = "your_tablename";参考:***.com/questions/1049728/… 我已经在 utf8 中了,但看起来我需要 utf8mb4 ***.com/questions/13653712/…【参考方案2】:

我通过blog post 设法存储了表情符号(占用 4 个字节):

Rails 4、MySQL 和表情符号 (Mysql2::Error: Incorrect string value error.)

您可能认为将大多数 utf8 数据插入到 当您指定 charset 为 utf-8 时到 mysql。可悲的是, 但是,你错了。问题是utf8字符集 存储在 VARCHAR 列中时占用3 bytes。表情符号字符,在 另一方面,占用 4 个字节

解决方案分为两部分:

更改表格和字段的编码:

ALTER TABLE `[table]` 
  CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
MODIFY [column] VARCHAR(250)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

告诉mysql2 适配器:

development:
  adapter: mysql2
  database: db
  username: 
  password:
  encoding: utf8mb4
  collation: utf8mb4_unicode_ci

希望这对某人有所帮助!

然后我不得不重新启动我的应用程序并且它工作。 请注意,一些表情符号在没有此修复的情况下可以工作,而有些则不能:

➡️ 成功了 ? 在我应用上述修复程序之前无法正常工作。

【讨论】:

通过终端访问mysql:sudo mysql -u root 为什么在database.yml 中将排序规则设置为utf8mb4_unicode_ci 而不是utf8mb4_bin 这对我来说终于可以用中文字符集了,谢谢! 适用于 Rails 6。不知道为什么这不是默认设置。【参考方案3】:

您可以使用这样的迁移将表转换为 utf8:

class ConvertTablesToUtf8 < ActiveRecord::Migration
  def change_encoding(encoding,collation)
    connection = ActiveRecord::Base.connection
    tables = connection.tables
    dbname =connection.current_database
    execute <<-SQL
      ALTER DATABASE #dbname CHARACTER SET #encoding COLLATE #collation;
    SQL
    tables.each do |tablename|
      execute <<-SQL
        ALTER TABLE #dbname.#tablename CONVERT TO CHARACTER SET #encoding COLLATE #collation;
      SQL
    end
  end

  def change
    reversible do |dir|
      dir.up do
        change_encoding('utf8','utf8_general_ci')
      end
      dir.down do
        change_encoding('latin1','latin1_swedish_ci')
      end
    end
  end
end

【讨论】:

【参考方案4】:

如果你想存储表情符号,你需要执行以下操作:

    创建迁移(感谢@mfazekas)

    类 ConvertTablesToUtf8

    定义改变 可逆做 |dir| dir.up 做 change_encoding('utf8mb4','utf8mb4_bin') 结尾 dir.down 做 change_encoding('latin1','latin1_swedish_ci') 结尾 结尾 结尾 结束

    将 rails 字符集更改为 utf8mb4(感谢 @selvamani-p)

    生产: 编码:utf8mb4

参考资料:

https://***.com/a/39465494/1058096

https://***.com/a/26273185/1058096

【讨论】:

谢谢。我认为您可以更改需要表情符号支持的特定列的字符集和排序规则 - 例如,如果将所有表更改为 utf8mb4 意味着现有索引键太长。迁移可以像这样执行 SQL:执行 很好,但是如果您忘记更改排序规则,您会收到错误。如果您使用工具来管理数据库,就会发生这种情况。一切视情况而定,如果您需要性能,您应该注意它,您的解决方案比我的更好。 这个答案看起来更像是对@mfazekas 对我的回答的评论。见"Why and how are some answers deleted?"【参考方案5】:

需要为已创建的数据库更改CHARACTER SETCOLLATE

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;

或者需要使用预设参数创建数据库:

CREATE DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;

【讨论】:

【参考方案6】:

从数据库获取数据时似乎存在编码问题。尝试将以下内容添加到您的 database.yml 文件中

   encoding: utf8 

希望这能解决您的问题

【讨论】:

MySQL 的 utf8 字符集只允许 unicode 的一个子集。此外,更改 database.yml 文件中的编码不会将数据库表本身转换为指定的编码。【参考方案7】:

另外,如果您不想更改数据库结构,您可以选择序列化相关字段。

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end

【讨论】:

在紧要关头工作,但绝对不是您正在寻找的长期解决方案。序列化内容的多个缺点。在某些时候正确配置数据库会更好。 @JoshuaPinter 您能否详细说明为什么使用序列化不是一个好的长期解决方案?目前正在尝试决定如何处理这种情况。 @BrandonSturgeon 我遇到过很多问题:随着该领域价值的增长,它可能变得笨拙且效率极低。它可能会达到字段数据库中的字符限制。我们存储了一个我们正在序列化的 id 值数组,而不是拥有正确的连接表,这意味着在检索这些 id 时无法正确使用数据库查询。很多东西是显而易见的,很多东西可能不是。只需谨慎使用它并注意其含义。 @JoshuaPinter 感谢您的回复!我决定通过迁移整理所有需要整理的表。这似乎也同样有效。我认为,另一个考虑因素是,如果您需要在 Rails 项目之外访问数据库,则必须单独实现反序列化方法。 @BrandonSturgeon 好点!同样,在紧要关头很好,但通常不是一个长期、强大的解决方案。

以上是关于Mysql2::Error: 不正确的字符串值的主要内容,如果未能解决你的问题,请参考以下文章

从 Mysql2::Error 中救援

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

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

C#,输入字符串的格式不正确,十进制值

日期时间格式无效:1366 字符串值不正确

如何在 Rails 中关闭 MySQL 严格模式