it-swarm.com.de

Mysql2 :: Fehler: Falscher Stringwert

Ich habe eine Rails-Anwendung, die im Produktionsmodus ausgeführt wird, aber plötzlich trat dieser Fehler auf, als ein Benutzer versuchte, einen Datensatz zu speichern.

Mysql2::Error: Incorrect string value

Weitere Details (aus dem Produktionsprotokoll):

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

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

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

Jetzt habe ich einige Lösungen gesehen, bei denen die Datenbanken gelöscht und neu erstellt werden mussten, aber ich kann das nicht.

Jetzt zeigt mysql das:

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)

Was ist falsch und wie kann ich es ändern, damit ich mit keinem Zeichen Probleme habe?

Außerdem: Kann dieses Problem mit Javascript gelöst werden? Konvertieren Sie es, bevor Sie es senden?

Vielen Dank

51
Trt Trt

das Problem wird durch den Zeichensatz Ihrer MySQL-Serverseite verursacht. Sie können manuell wie folgt konfigurieren:

ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8

oder lassen Sie die Tabelle fallen und erstellen Sie sie wie folgt:

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

verweise:

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

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

UPDATE

der erste Befehl wirkt sich nur auf die angegebene Tabelle aus. Wenn Sie alle Tabellen in einer Datenbank ändern möchten, können Sie dies auch tun

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;

referenz:

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

69
Chuanpin Zhu

Ich habe es geschafft, Emojis (die 4 Bytes beanspruchen) zu speichern, indem ich diesem blog post folgte:

Rails 4, MySQL und Emoji (Mysql2::Error: Incorrect string value error.)

Sie denken vielleicht, dass Sie die meisten utf8-Daten sicher in .__ einfügen können. zu mysql, wenn Sie angegeben haben, dass der Zeichensatz utf-8 ist. Traurig, Sie sind jedoch falsch. Das Problem ist, dass der utf8-Zeichensatz belegt 3 Byte , wenn in einer VARCHAR-Spalte gespeichert. Emoji-Zeichen auf Nehmen Sie andererseits 4 Bytes in Anspruch. 

Die Lösung besteht aus 2 Teilen:

Ändern Sie die Kodierung Ihrer Tabelle und Felder:

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

Erzählen Sie dem mysql2-Adapter davon:

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

Hoffe das hilft jemandem!

Dann musste ich meine App neu starten und es hat funktioniert .. Bitte beachten Sie, dass einige Emojis ohne dieses Update funktionieren, andere jedoch nicht:

  • ➡️ Hat funktioniert
  • ???? Hat nicht funktioniert, bis ich die oben beschriebene Korrektur angewendet habe.
34
Besi

Sie können eine solche Migration verwenden, um Ihre Tabellen in utf8 zu konvertieren:

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
23
mfazekas

Wenn Sie Emoji speichern möchten, benötigen Sie:

1) Erstellen Sie eine Migration (danke @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) Den Zeichensatz von Rails in utf8mb4 ändern (danke @ selvamani-p)

production:
  encoding: utf8mb4

Verweise:

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

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

2
dtelaroli

CHARACTER SET und COLLATE müssen für bereits erstellte Datenbanken geändert werden:

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Oder es war notwendig, eine Datenbank mit voreingestellten Parametern zu erstellen:

CREATE DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
1
shilovk

Wenn Sie keine Änderungen an Ihrer Datenbankstruktur vornehmen möchten, können Sie das betreffende Feld auch serialisieren.

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end
0
Paul Marclay

Es scheint ein Codierungsproblem beim Abrufen von Daten aus der Datenbank zu sein. Versuchen Sie, das Folgende der Datei database.yml hinzuzufügen

   encoding: utf8 

Hoffe, das löst dein Problem

0
Dhepthi

Ich kam gerade darüber und schätze @ mfazekas 'Antwort. Ich habe zwei Änderungen an der Migration vorgenommen: eine, um das Entfernen von connection.current_database (zumindest in Rails 5) zu ermöglichen, und die Möglichkeit, die SQL-Anweisungen zu überspringen, wenn MySQL nicht verwendet wird (ich verwende immer noch SQLite in der Entwicklung, aber die Migration muss ausgeführt werden ).

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
0
mrturtle