2017-08-07 2 views
1

Je rencontre des problèmes avec un déclencheur de base de données qui enregistre toutes les requêtes effectuées sur une table, lorsque cette requête contient un UTF de 4 octets. 8 caractères.Problème d'insertion de caractères/emoji UTF-8 de 4 octets dans la base de données MySQL lorsque le déclencheur d'insertion est actif

Mon mysql.cnf

version MySQL est 5.7.19 sur Ubuntu 16.04

script Exemple:

show variables where Variable_name like 'character\_set\_%' or Variable_name like 'collation%'; 

drop database if exists my_test_db; 
create database my_test_db; 
use my_test_db; 

create table my_test_table(id int not null primary key auto_increment, jdoc json not null); 
create table my_test_table_log(id int not null primary key auto_increment, query varchar(1024) NOT NULL); 

SELECT "insert works when trigger is not active" as ""; 
insert into my_test_table(jdoc) VALUES(JSON_OBJECT("Dubai was", "")); 

DELIMITER | 
CREATE TRIGGER log_my_test_table_queries_insert 
BEFORE INSERT ON `my_test_table` 
FOR EACH ROW 
    BEGIN 
    DECLARE original_query VARCHAR(1024); 
    SET original_query = (SELECT info 
          FROM INFORMATION_SCHEMA.PROCESSLIST 
          WHERE id = CONNECTION_ID()); 
    INSERT INTO `my_test_table_log` (`query`) VALUES (original_query); 
    END; 
| 
DELIMITER ; 

SELECT "insert doesn't work when trigger is active" as ""; 
insert into my_test_table(jdoc) VALUES(JSON_OBJECT("Dubai was", "")); 

Ma sortie:

+--------------------------+--------------------+ 
| Variable_name   | Value    | 
+--------------------------+--------------------+ 
| character_set_client  | utf8mb4   | 
| character_set_connection | utf8mb4   | 
| character_set_database | utf8mb4   | 
| character_set_filesystem | binary    | 
| character_set_results | utf8mb4   | 
| character_set_server  | utf8mb4   | 
| character_set_system  | utf8    | 
| collation_connection  | utf8mb4_unicode_ci | 
| collation_database  | utf8mb4_unicode_ci | 
| collation_server   | utf8mb4_unicode_ci | 
+--------------------------+--------------------+ 
10 rows in set (0.00 sec) 

Query OK, 2 rows affected (0.03 sec) 

Query OK, 1 row affected (0.00 sec) 

Database changed 
Query OK, 0 rows affected (0.03 sec) 

Query OK, 0 rows affected (0.02 sec) 

+-----------------------------------------+ 
|           | 
+-----------------------------------------+ 
| insert works when trigger is not active | 
+-----------------------------------------+ 
1 row in set (0.00 sec) 

Query OK, 1 row affected (0.00 sec) 

Query OK, 0 rows affected (0.01 sec) 

+--------------------------------------------+ 
|           | 
+--------------------------------------------+ 
| insert doesn't work when trigger is active | 
+--------------------------------------------+ 
1 row in set (0.01 sec) 

ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x94\xA5")...' for column 'INFO' at row 1 

Les bases de données semblent être créé avec le jeu de caractères correct

SHOW CREATE TRIGGER log_my_test_table_queries_insert; 
SHOW CREATE TABLE my_test_table; 
SHOW CREATE TABLE my_test_table_log; 

outputs

detailsdetailsdetails

Répondre

2

Cela se produit parce que information_schema.processlist utilise le jeu de caractères UTF8mb3. (UTF est un alias à UTFmb3). Cette simple requête illustre ceci:

mysql> select info, "" from information_schema.processlist; 
+------------------------------------------------------+------+ 
| info             | ? | 
+------------------------------------------------------+------+ 
| select info, "?" from information_schema.processlist |  | 
+------------------------------------------------------+------+ 
1 row in set, 1 warning (0,00 sec) 

Warning (Code 1366): Incorrect string value: '\xF0\x9F\x94\xA5" ...' for column 'INFO' at row 1 

L'avertissement ci-dessus entraînera probablement une erreur lorsque le déclencheur tente d'insérer le contenu de la colonne info dans une autre table.

Je pense que le problème est que la chaîne de requête est stockée telle quelle dans la table processlist sans la convertir en jeu de caractères attendu. J'ai déposé un bug report à ce sujet.

+0

Y a-t-il des nouvelles? – Philippe

0

-ce que ces

SHOW CREATE TRIGGER log_my_test_table_queries_insert; 
SHOW CREATE TABLE my_test_table; 
SHOW CREATE TABLE my_test_table_log; 

Je pense que vous trouverez qu'ils ont été créés avec le mauvais charset en vigueur.

La modification de cette une ligne peut suffire:

create database my_test_db CHARACTER SET utf8mb4; 

(je ne peux pas reproduire le problème avec votre cas de test Quelle version de MySQL ou MariaDB utilisez-vous.?)

+0

J'ai ajouté quelques informations supplémentaires à la publication originale. Tristement en spécifiant explicitement le jeu de caractères sur la création de la base de données n'a pas résolu le problème. utf8mb4 est spécifié globalement dans le fichier mysql.cnf – Philippe

+0

Que voulez-vous dire par reproduction? Est-ce que le script s'exécute sans problème sur votre machine? – Philippe