mysql隐式转换 “undefined“字符串匹配到mysql int类型0值字段

描述:mysql 用字符串搜索 能搜到int类型查询结果
mysql int类型条件用字符串查询

table:

CREATE TABLE `all_participate_records` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
  `deleted_at` datetime(3) DEFAULT NULL,
  `missionid` bigint DEFAULT NULL,
  `userid` bigint DEFAULT NULL,
  `participateid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_all_participate_records_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=126 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

本来是用这条sql去查数据的,userid的值应该int类型。

SELECT DISTINCT missionid FROM `all_participate_records` WHERE userid = 123456

但是我在后端代码里并没有将string类型的参数转为int,而是直接将string类型的参数传进了sql里。于是就成了下面这样的sql

SELECT DISTINCT missionid FROM `all_participate_records` WHERE userid = '123456'

这样的话,每次参数都会以String类型去传到SQL里进行搜索,但是实际上sql里的这个字段是int类型的,所以就会发生隐式转换。

根据隐式转换的规则,我所有的字符串的类型都会被转换为数字类型,那么我的。字符串转换为数字之后就变成了0,所以就会匹配到这个字段为0的记录。

这个时候前端给我传参’undifined’,发生了这个错误,就是因为它将undifined转换成了0,就会匹配到那些为零的记录。

在 MySQL 中,字符串和数字做比较的话,是将字符串转换成数字。就比如上面那条sql会把varchar类型的userid字段转换成int类。
它会将传入的字符串字段截取,从第一位int型开始到第一个非int型的值作为条件。

比如下边的例子,将ff的字符串放在最后不影响查询,但是如果将字符串放在了数字的前边,那么就会截取到字符串的位置,导致匹配不上。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
同时 我们可以将字符串类型转换为int 试下,发现字符串类型 全被转换成了 0 。

在这里插入图片描述


使用的时候 如果遇到类似问题,那么有以下方法避免出现问题:

  • 一是 尽可能杜绝隐式转换,在给sql语句传参的时候就将参数转换为正确的,与表结构一致的数据类型。这一步在做的时候 也会将包含字符串的参数排除掉(可能会触发error,eg: {“code”:500,“msg”:“err : strconv.Atoi: parsing “undefined”: invalid syntax”}% )
  • 二是 在数据校验层就将类似“undefined”这样的参数过滤掉。最好用post传参,方便效验字段类型。
  • 三是 数据层,如果刚好你的字符串在参数的第一位,那么就会将这个参数直接转换为0。所以 在数据库中尽量杜绝空值或者默认值的写入,像“xxxid”这种字段为0值(或默认值)是不合理的。
    我这里是因为之前造的假数据。才会有0值存在,正常逻辑走时不会有userid为空的情况发生的。
    另外注意 ⚠️ 隐式转换 会破坏索引 所以最优解就是 第一种 将相应字段数据类型保持一致,不要用string去搜索int

referrence:mysql int类型条件用字符串查询
参考
参考

猜你喜欢

转载自blog.csdn.net/qq_37106501/article/details/129768134
今日推荐