Mysql2 ::错误:字符串值不正确

时间:2014-03-17 19:52:38

标签: mysql ruby-on-rails ruby encoding

我有一个在生产模式下运行的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解决吗?在发送之前转换它?

由于

8 个答案:

答案 0 :(得分:72)

问题是由mysql服务器端的charset引起的。您可以手动配置:

ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8

或删除表并重新创建它:

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

的引用:

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

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

<强>更新

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

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;

参考:

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

答案 1 :(得分:38)

我设法按照blog post来存储表情符号(占用4个字节):

  

Rails 4,MySQL和Emoji(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
     

希望这有助于某人!

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

  • ➡️做了工作
  • 在我应用上述修复程序之前没有工作。

答案 2 :(得分:23)

您可以使用此类迁移将表格转换为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

答案 3 :(得分:2)

如果你想要商店表情符号,你需要:

1)创建迁移(感谢@mfazekas)

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('utf8mb4','utf8mb4_bin')
      end
      dir.down do
        change_encoding('latin1','latin1_swedish_ci')
      end
    end
  end
end

2)将rails charset更改为utf8mb4(感谢@ selvamani-p)

production:
  encoding: utf8mb4

参考文献:

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

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

答案 4 :(得分:1)

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

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;

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

CREATE DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;

答案 5 :(得分:0)

从数据库获取数据时,这似乎是一个编码问题。尝试将以下内容添加到database.yml文件

   encoding: utf8 

希望这能解决您的问题

答案 6 :(得分:0)

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

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end

答案 7 :(得分:0)

刚刚遇到这个问题,并感谢@mfazekas的回答。我在迁移中进行了两项更改:一种用于适应从connection.current_database中删除(至少在Rails 5中),以及如果不使用MySQL则可以跳过SQL语句的能力(我仍在开发中使用SQLite,但需要运行迁移)。

class ConvertTablesToUtf8 < ActiveRecord::Migration[5.2]
  def change_encoding(encoding,collation)
    # Allow for different adapter in different environment
    return unless ActiveRecord::Base.connection_config[:adapter] == "mysql"
    tables = connection.tables
    dbname = ActiveRecord::Base.connection_config[: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