2017-08-07 37 views
1

如果數據庫觸發器記錄了在表上執行的所有查詢,並且該查詢包含4字節的UTF- 8個字符。當插入觸發器處於活動狀態時,將4字節UTF-8字符/表情符號插入MySQL數據庫時遇到問題

mysql.cnf

MySQL的版本是19年7月5日在Ubuntu 16.04

示例腳本:

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", "")); 

我的輸出:

+--------------------------+--------------------+ 
| 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 

數據庫似乎與創造正確的字符集

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

outputs

detailsdetailsdetails

回答

2

這是因爲information_schema.processlist正在使用UTF8mb3字符集。 (UTF是UTFmb3的別名)。這個簡單的查詢說明這一點:

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 

上述警告可能導致錯誤當觸發試圖將info列的內容插入到另一個表。

我認爲問題在於查詢字符串按原樣存儲在processlist表中,而沒有將其轉換爲預期的字符集。我已經提交了關於此的bug report

+0

有什麼消息嗎? – Philippe

0

做這些

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

我懷疑你會發現,他們與生效錯誤的字符集創建。

改變這一行就足夠了:

create database my_test_db CHARACTER SET utf8mb4; 

(我不能與你的測試用例是您使用的MySQL或MariaDB的版本重現問題?)

+0

我在原帖中增加了一些附加信息。令人遺憾的是,在數據庫創建中明確指定字符集並未解決問題。在mysql.cnf文件中全局指定了utf8mb4 – Philippe

+0

重現的意思是什麼?腳本在您的機器上執行沒有問題? – Philippe

相關問題