mysql group_concat 与 union 联合查询漏洞,数据列最大长度为341
一、问题发现
最近 项目反馈有个问题,数据明明存在,但是到界面显示就少了一部分。
界面框框数据本应该勾选的,但是就是不勾选!
二、问题分析
经系列排查,发现问题所在 mysql group_concat 与 union 联合查询漏洞;
select * from (
select GROUP_CONCAT(subsystem_code) subsystem_code from code_temp where id <41
union all
select code as subsystem_code from code_temp2
) temp;
select GROUP_CONCAT(subsystem_code) subsystem_code from code_temp;
单个 GROUP_CONCAT 无论多个 subsystem_code都不存在任何问题,但是当 套上 union 之后,id 扩大到41时,GROUP_CONCAT(subsystem_code) 数据就被截取了,且字符串最大长度为 341.
mysql 官方说明:
The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. The value can be set higher, although the effective maximum length of the return value is constrained by the value of max_allowed_packet.
即 mysql group_concat_max_len所指定的,默认是1024,单位是byte,划算成字符要打折扣 341=1024/3
;
show variables like 'group_concat_max_len';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| group_concat_max_len | 1024 |
+----------------------+-------+
1 row in set (0.00 sec)
三、问题解决
可以修改,修改办法如下:
方法一:修改MySQL配置文件my.cnf,在[mysqld]节点中添加
group_concat_max_len = 18446744073709551615
方法二:直接控制台上设置立即生效
-- 【必须操作】更改全局配置----
SET GLOBAL group_concat_max_len=18446744073709551615;
-- 【可选操作】使配置在当前会话中也立即生效,其它已经登录的会话终端需要重启生效----
SET SESSION group_concat_max_len=18446744073709551615;
方法三:业务层修正 (推荐)
通常的办法其实是让数据库返回一个列表,在应用服务层,进行join