网站首页 > 基础教程 正文
事件起源与分析
收到客户发来的请求报文,入库后发现有些字符不能正常显示。查看日志发现insert操作中,字段内容没有问题。于是开始排查:
首先我们先来查看当前数据库的字符集
show variables like ‘character_set_%’
结果如下
Variable_name Value
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_results utf8mb4
character_set_server utf8mb4
character_set_database utf8mb4
character_set_system utf8
character_sets_dir C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\
character_set_filesystem binary
各个字段具体意义如下:
- character_set_client
主要用来设置客户端使用的字符集。通俗的讲就是mysql把客户端传递过来的数据都当成是utf8mb4 - character_set_connection
主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置。 - character_set_database
主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置。 - character_set_filesystem
文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的。 - character_set_results
数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式。通俗的讲就是mysql发送个客户端的数据是utf8mb4的 - character_set_server
服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要人为定义。 - character_set_system
数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。 - character_sets_dir
这个变量是字符集安装的目录。
通过以上信息进行分析,我们可以推断
- 插入语句没有问题
- 后台字符集为utf8mb4,支持生僻字
剩下只能是程序连接数据库时是否设置了什么,进一步排查代码发现MySQL建立连接之后执行了如下语句,原因找到了。
mysql_set_character_set(mysql, "utf8");
解决方法
mysql在C/C++中调用api设置连接mysql的编码方式有以下几种方法:
1. mysqli_set_charset
ret = mysql_set_character_set(mysql, "utf8mb4");
ret = mysql_set_character_set(mysql, "utf8mb4");
说明:
推荐使用的设置方法,与mysql的连接断开自动重连后仍能保持设置的编码格式,并且影响mysql_real_escape_string函数功能,使mysql_real_escape_string函数使用设置的编码格式转义字符串。
2. 执行sql语句:SET NAMES
ret = mysql_real_query(mysql, "SET NAMES UTF8MB4;",
(unsigned long) strlen ("SET NAMES UTF8MB4;"));
ret = mysql_real_query(mysql, "SET NAMES UTF8MB4;",
(unsigned long) strlen ("SET NAMES UTF8MB4;"));
说明:
使用sql语句执行,只能影响当前与数据库的连接,断开自动重连后编码格式会重置为默认的配置。
3. 设置MYSQL_SET_CHARSET_NAME属性
ret = mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
ret = mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
说明:
跟mysql_set_character_set类似,断开自动重连后仍能保持设置的编码格式,只是不会影响到mysql_real_escape_string函数。 需要特别说明的是只有在调用mysql_real_connect连接数据库之前修改该属性才会生效。
猜你喜欢
- 2024-10-12 Linux库函数调用工具—ltrace命令
- 2024-10-12 C/C++恶意代码盘点(二):后门丨文件监控丨自删除功能
- 2024-10-12 C语言文件的随机读写、块读写、行、字符读写以及格式化输入输出
- 2024-10-12 C/C++恶意代码盘点(一):进程遍历丨木马病毒丨密码记录
- 2024-10-12 C/C++连接MySql数据库使用总结 c++连接数据库sqlserver
- 2024-10-12 CAD常用语言函数 cad常用语言函数有哪些
- 2024-10-12 PHP压缩ZIP中文注释乱码问题解决办法
- 2024-10-12 Android Dalvik 使用详解 android dac
- 2024-10-12 C++|整型的最值、上溢、下溢、截断、类型提升和转换
- 2024-10-12 # Redis 入门到精通(一)数据类型(1)
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)