如何使这个 MySQL 函数不会弄乱我的字符集?

Posted

技术标签:

【中文标题】如何使这个 MySQL 函数不会弄乱我的字符集?【英文标题】:How to make this MySQL function not mess up my character set? 【发布时间】:2015-12-17 15:39:05 【问题描述】:

我需要一个 mysql 函数来修剪字符串开头和结尾的所有空格(包括换行符和制表符),所以我创建了以下函数:

DROP FUNCTION IF EXISTS WSTrim;
DELIMITER $$
CREATE FUNCTION `WSTrim`(text LONGTEXT CHARSET utf8) RETURNS LONGTEXT CHARSET utf8
    NO SQL
    DETERMINISTIC
BEGIN
 RETURN TRIM(REPLACE(REPLACE(REPLACE(text, '\t', ' '), '\r', ' '), '\n', ' '));
END$$
DELIMITER ;

尽管它在参数声明和返回值规范中说了些什么,但这个函数弄乱了我的字符集,我希望它是utf8。如果我这样调用这个函数:

INSERT INTO mytable (name) VALUES (WSTrim(' ČĆŽŠĐ čćžšđ   '));

我收到警告

1 row(s) affected, 1 warning(s): 1366 Incorrect string value: '\xC4\x8C\xC4\x86\xC5\xBD...' for column 'name' at row 1

如何更改我的功能以免弄乱我的角色?

编辑 1:

我使用的连接字符串是

Server=myserver;Port=myport;Database=mydb;Uid=myuid;Pwd=mypwd;CharSet=utf8

另外,为了完整性,

mysql> show variables where Variable_name like 'character%' or Variable_name like 'collation%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8_general_ci            |
| collation_database       | utf8_unicode_ci            |
| collation_server         | utf8_unicode_ci            |
+--------------------------+----------------------------+

注意,即使我连接 MySQL Workbench,而不仅仅是我的应用程序,也会发生同样的事情。

编辑 2:

INSERT INTO mytable (name) VALUES (' ČĆŽŠĐ čćžšđ   ');

这会正确插入值。

编辑 3:

mysql> SELECT WSTrim(' ČĆŽŠĐ čćžšđ ');
+-----------------------------------+
| WSTrim(' ČĆŽŠĐ čćžšđ ')           |
+-----------------------------------+
| ??ŽŠ? ??žš?                       |
+-----------------------------------+
1 row in set, 1 warning (0.01 sec)

我如何发送查询并不重要。但是,我注意到如果我输入了

show function status;

返回的行之一是:

+------+--------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db   | Name   | Type     | Definer        | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------+--------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| mydb | WSTrim | FUNCTION | mydb@localhost | 2015-11-23 04:01:06 | 2015-11-23 04:01:06 | DEFINER       |         | latin1               | latin1_swedish_ci    | latin1_swedish_ci  |
+------+--------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+

由于某种原因,它使用latin1 处理函数。但是我该如何改变呢?

编辑 4:

mysql> show create database mydb;
+----------+---------------------------------------------------------------------------------------+
| Database | Create Database                                                                       |
+----------+---------------------------------------------------------------------------------------+
| mydb     | CREATE DATABASE `mydb` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */ |
+----------+---------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

【问题讨论】:

在我的系统上,您的功能可以正常工作。您的问题可能是由于连接字符串 - 检查它的设置。 makandracards.com/makandra/… @PaulF,我已经编辑了答案。 你检查过函数返回的内容吗:SELECT WSTrim('ČĆŽŠĐ čćžšđ'); 对我来说从控制台按预期工作。如果你在命令行打开mysql,你会得到什么?您如何将查询发送到数据库? SHOW FUNCTION STATUS 不是这么说的:dev.mysql.com/doc/refman/5.7/en/show-procedure-status.html 【参考方案1】:

根据the documentation,SHOW FUNCTION STATUS 中的character_set_clientcollation_connection 列表明您在创建函数期间未连接到utf8。您可能需要检查连接设置以确保您没有在某处定义 latin1。

同样,Database Collation 列表示数据库本身定义为 latin1。

【讨论】:

以上是关于如何使这个 MySQL 函数不会弄乱我的字符集?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 fread 会弄乱我的字节顺序?

为啥 PHP 会弄乱我的 CSS?

为啥画布会弄乱我的图像颜色?

为啥浏览器的后退按钮会弄乱我的 Vue 组件?

MySQL 并发更新

如何使用 PHP 从输入框中删除引号