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

文章讨论了在MySQL中,当使用字符串搜索INT类型的字段时,会发生隐式转换,可能导致不期望的结果。例如,undefined会被转换为0,匹配到ID为0的记录。为了避免这类问题,建议在传参时确保数据类型正确,提前进行数据校验,并避免使用可能引发错误的默认值或空值,以保护数据库的索引效率。
摘要由CSDN通过智能技术生成

描述: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类型条件用字符串查询
参考
参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值