关于mysql版本差异导致FIND_IN_SET()查询不到数据的问题

2023-05-16

这次发现的问题,是在接手项目的时候,和安卓端小伙伴测试时候发现的,插入数据之后却查不出来,通过排查定位到FIND_IN_SET()函数,也是第一次接触FIND_IN_SET(),特此记录一下~

关于FIND_IN_SET():

官方涵义(MySQL手册中语法说明)

FIND_IN_SET(str,strlist) : str 要查询的字符串,strlist 需查询的字段,参数以”,”分隔,形式如 (1,2,6,8,10,22);该函数的作用是查询字段(strlist)中是否包含(str)的结果,返回结果为null或记录。

假如字符串str在由N个子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。 一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则FIND_IN_SET() 函数被优化,使用比特计算。 如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号( , )时将无法正常运行。数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号( , )时将无法正常运行。

示例:

SELECT FIND_IN_SET('b', 'a,b,c,d');

// 结果:2

// 因为 b 在strlist集合中2的位置, a是位置1

select FIND_IN_SET('1', '1');

// 结果:1

// 这时候的strlist集合有点特殊,只有一个字符串

select FIND_IN_SET('2', '1,2');

// 结果:2

select FIND_IN_SET('6', '1');

// 结果:0 strlist中不存在str,所以返回0。

综上: FIND_IN_SET函数中,若前一个字符串包含在后一个字符串集合中,返回大于0的数,该数为前一个字符串在后一个字符串中的位置。

问题发生:

有一张发布作业表,表中有个varcher类型字段用于存储班级id,存入的形式是 ‘01,02,03’,而现在要用另外一张表,通过学生所在的班级id,从发布作业表中获取相关老师布置的作业,,接手项目时,sql语句如下:

SELECT

m.class_id,

m.prod_key,

m.dev_name,

w.id work_id,

w.title,

w.content,

w.is_open,

w.score,

w.file_url_list,

w.end_time,

w.create_author,

w.update_author

FROM

sc_work w,

sc_class_mem m

WHERE

w.id = 56

AND find_in_set(m.class_id, w.class_ids)

AND m.identity=0;

问题解决:

在安卓小伙伴进行测试的时候所拿到的相关字段数据是空的,通过debug发现执行这个sql语句后,获取到的值是null。但是本地数据与测试服务器的数据库数据是一致的,所以应该可以查询到值才对,所以我认为是前者写的sql语句有问题(因为此前就有出现过好几次这个问题,再加上我在本地执行sql语句查询不到任何数据),但我还是将映射文件中的sql语句放到测试服务器的数据库执行发现是可以查询到的,首先想到的是不是本地mysql版本(8.0.26)不支持这个函数,但是实际发现是支持的,然后又去看了一下库中表的字符集,发现是utf32,而我创建的时候是utf8mb4,然后便重新创建库,字符集选了utf32,测试是不是这个原因,但是实际结果发现并不是这个原因,于是便去查询相关资料,以及修改sql语句,我发现:

find_in_set(m.class_id, '45,46,46')

如果将两个字段任一换成’xx,xx,xx’,就可以查询的到,就很奇怪。

而网上资料全是讲解如何使用,千篇一律,没有起到帮助,想了很久,虽然一开始有想到了是不是数据库版本的问题,但是没有马上去测试这个想法,因为我觉得8.0.19和本地8.0.26应该差别不大才对啊,而且官方文档这个函数还存在,版本越高不是越能向下兼容? 查了一天,想了很久不知道问题出在哪里,最后还是在虚拟机拉取了一个mysql8.0.19的镜像下来,进行测试,最终发现是数据库版本的问题,至此问题得到解决,又长见识了~

漂亮!又浪费了一天时间~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于mysql版本差异导致FIND_IN_SET()查询不到数据的问题 的相关文章

随机推荐