一、发现问题

1、在一次MySQL查询中,某字段为 varchar 字符串类型,传入参数值为 int 数字类型,发现查询的结果和预期的不一致。 如: 某两列 name='11' , name = '11aa' 。 where name = 11 , 可以查到 '11' 和 '11aa' 两个结果,这里是错误的;而 where name ='11' ,能得到预期结果。

2、反之,字段为 int 数字类型,传入参数值为 varchar 字符串类型,也能查到数据,同样查询的结果和预期的不一致。如:age=2的数据有2条。where age = 2 , 可以正常查到数据 ; 而 where age = '2aabbcc',查到的数据结果和 where age = 2 是一样的,这里是错误的,应该查不到数据。

二、代码理解

1、针对【一】中的问题,描述的不好理解,晦涩难懂,下面用代码加以理解,推动理解问题!

2、在MySQL数据中,创建一个 implicit 表 , 如下: (MySQL version 5.7+)

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for implicit

-- ----------------------------

DROP TABLE IF EXISTS `implicit`;

CREATE TABLE `implicit` (

`id` varchar(255) NOT NULL COMMENT '编号',

`name` varchar(255) DEFAULT NULL COMMENT '名称',

`age` int(11) DEFAULT NULL COMMENT '年龄',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='MySQL Implicit conversion (MySQL 隐式类型转换)';

-- ----------------------------

-- Records of implicit

-- ----------------------------

INSERT INTO `implicit` VALUES ('11', '小明', '2');

INSERT INTO `implicit` VALUES ('11qq', '小红', '2');

INSERT INTO `implicit` VALUES ('12', '小新', '54');

INSERT INTO `implicit` VALUES ('tt11', '小刚', '92');

3、implicit 表数据如下:

三、针对问题进行测试

1、字段类型是 varchar 字符串,传入参数为 int 数字类型 。

1.1、-- 字段类型是 varchar ,传入参数是 varchar 【预期正确结果】

SELECT * FROM implicit a WHERE a.id = '11' ;

1.2、-- 字段类型是 varchar , 传入参数是 int 【错误结果】

SELECT * FROM implicit a WHERE a.id = 11 ;

2、字段类型是 int 数字类型,传入参数为 varchar 字符串类型。

2.1、-- 字段类型是 int类型,传入参数是 int类型 【预期正确结果】

SELECT * FROM implicit a WHERE a.age = 2 ;

2.2、-- 字段类型是 int类型,传入参数是varchar类型 【错误结果】

SELECT * FROM implicit a WHERE a.age = '2aa' ;

四、问题原因及避免

1、原因: 当MySQL字段类型和传入条件数据类型不一致时,会进行隐形的数据类型转换(MySQL Implicit conversion)

2、若字符串是以数字开头,且全部都是数字,则转换为数字结果是整个字符串;部分是数字,则转换为数字结果是截止到第一个不是数字的字符为止。 理解: varchar str = "123dafa",转换为数字是123 。 SELECT '123dafa'+1 ; --- 124 。

3、若字符串不是以数字开头,则转换为数字结果是 0 。 varchar str = "aabb33" ; 转换为数字是 0 。 SELECT 'aabb33'+100 ; --- 100 。

4、更多隐式转换规则摘录:

两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换

两个参数都是字符串,会按照字符串来比较,不做类型转换

两个参数都是整数,按照整数来比较,不做类型转换

十六进制的值和非数字做比较时,会被当做二进制串

有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp

有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较

所有其他情况下,两个参数都会被转换为浮点数再进行比较。

五、问题总结

1、MySQL 隐式转换问题,隐藏的深,不容易被发现,在进行 delete , update 等操作时,一不小心很容易大问题,从而造成事故。

2、对于 delete , update 等操作时,建议先使用 select 语句,看看获取的结果和预期的是否一致,再进行操作,相对会更安全一些。

3、为了便于更好理解,MySQL 隐式转换规则,增加下面sql测试理解。

3.1、SELECT 'a10'+10 ; -- 10

SHOW WARNINGS ; -- WARNINGS: Truncated incorrect DOUBLE value: 'a10'

查看warnings可以看到隐式转化把字符串转为了double类型。但是因为字符串是非数字型的,所以就会被转换为0,因此最终计算的是0+10=10 .

3.2、SELECT '10a'+10 ; -- 20

SHOW WARNINGS ; -- WARNINGS: Truncated incorrect DOUBLE value: '10a'

3.3、SELECT 'a'=0 ; -- 1 , 相当于 true

SHOW WARNINGS ; -- WARNINGS: Truncated incorrect DOUBLE value: 'a'

3.4、SELECT 'a23423' = 0 ; -- 1 , 相当于 true

SHOW WARNINGS ; -- WARNINGS:Truncated incorrect DOUBLE value: 'a23423'

3.5、SELECT '11dafdfwwe'=11; -- 1, 相当于 true

SHOW WARNINGS ; -- WARNINGS:Truncated incorrect DOUBLE value: '11dafdfwwe'

3.6、SELECT 11= 11 ; -- 1, 相当于 true

SHOW WARNINGS ; -- 无

3.7、SELECT 'abc'='abc' ; -- 1, 相当于 true

SHOW WARNINGS ; -- 无

3.8、SELECT 'abc'='abc232322' ; -- 0 , 数据类型一样,不会进行转换

SHOW WARNINGS ; -- 无

3.9、SELECT 'a'+'b'; -- 0 , 都转换为0了, 0+0=0 。

SHOW WARNINGS ; -- WARNINGS: Truncated incorrect DOUBLE value: 'a' , Truncated incorrect DOUBLE value: 'b'

3.10、SELECT 'a'+'b'='c' ; -- 1 ,等价于 0+0=0 --> 0=0=1。

SHOW WARNINGS ; -- WARNINGS: Truncated incorrect DOUBLE value: 'a' , Truncated incorrect DOUBLE value: 'b' , Truncated incorrect DOUBLE value: 'c'

mysql 将字符串转换数字类型的_MySQL 字符串类型用数字可以查出来 MySQL字符串类型会转换成数字 MySQL隐式类型转换...相关推荐

  1. 《MySQL tips:隐式类型转换与隐式字符编码转换对查询效率的影响》

    维护一个交易系统,交易记录表tradelog包含交易流水号(tradeid).交易员id(operator).交易时间(t_modified)等字段. create table 'tradelog' ...

  2. html中隐式转换成数字,详解JS中的隐式类型转换

    JS中隐式类型转换 JS中的数据类型 JS中的数据类型分为两大类: 1.基本数据类型: 1.String 字符串 表示一段文本,例如:人的姓名.地址等 2.Number 数值 3.Boolean 布尔 ...

  3. Mysql 隐式类型转换

    一.实例操作 如下图user表结构 查询语句1 执行结果: 查询语句2 执行结果: 查询语句3 执行结果: 查询语句4 执行结果: 结果分析: 从上面四则查询语句中可以看出 mobile的字段为字符类 ...

  4. MySQL的隐式类型转换

    引入 在项目中调用别的部门的模糊查询接口,发现还根据模糊字段搜索主键,还搜出了结果.SQL大概是这个意思Select * from tablea where name like "%1Tes ...

  5. C语言操作符详解 隐式类型转换 (整型提升 算数转换)

    目录 一.算术操作符 二.左移操作符 右移操作符 1.二进制序列 2.左移操作符 3.右移操作符 3.1.逻辑运算/算术运算 3.2.对于移位运算符,不要移动负数位,这是标准未定义的 3.3.对于移位 ...

  6. mysql 注入关键字waf_利用mysql的隐式类型转换绕过waf注入

    今天做的一道ctf题,要求绕过waf去注入,可以通过mysql隐式类型转换的特性去绕过waf,在这里记录下来供大家学习一下 题目地址:题目地址(比赛结束后可能会失效) HINT:我都过滤了,看你怎么绕 ...

  7. Mysql隐式类型转换

    概述 在开发规范中,我们往往会要求研发避免在where条件中出现隐式类型转换,这么要求大概有以下两方面的原因: 隐式类型转换可能导致索引失效: 隐式类型转换可能产生非预期的结果. 何为隐式转换:即在w ...

  8. 隐式类型转换与转换操作符operator T

    隐式类型转换与转换操作符 operator T C++ 标准允许隐式类型转换,即对特定的类,在特定条件下,某些参数或变量将隐形转换成类对象 ( 创建临时对象 ) .如果这种转换代价很大 ( 调用类的构 ...

  9. python隐式类型转换_JS 类型隐式转换

    1.js数据类型 js中有7种数据类型,可以分为两类:原始类型.对象类型: 基础类型(原始值): Undefined. Null. String. Number. Boolean. Symbol (e ...

最新文章

  1. memcache基础教程
  2. 发力大陆移动VR,HTC刚刚发布ViveWave开放平台和ViveFocus一体机
  3. ad19生成gerber文件_在“AD19”中怎样将PCB文件转换为GERBER
  4. C++---肿瘤面积
  5. 关于eclipse中文注释乱码的问题
  6. JavaScript时间事件:setTimeout和setInterval
  7. 解决Linux 忘记root 密码的办法
  8. pod 挂载点 mysql_Pod挂载(Secret )
  9. java extends 继承的一些小结。
  10. Ubuntu16.04安装系统之后软件无法安装
  11. 微擎系统 微信支付 get_brand_wcpay_request:fail
  12. 【爷青回系列】使用VMware虚拟机安装Windows XP系统!最详细!
  13. 工行u盾显示316_详解工行U盾及使用方法和注意事项
  14. oracle财务系统名称,Oracle财务系统总账模块操作手册
  15. java List/ArrayList 解惑
  16. CSS选择器(id选择器,包含选择器,标签名选择器,类选择器,属性选择器,通配符选择器,伪类选择器,相邻选择器,选择器的优先级,子选择器)
  17. callback 回调函数
  18. 【Web技术】919- 前端关于单点登录的知识
  19. 5.8月更新下 青龙面板——酷狗大字版(教程很难吗?)
  20. 软件测试转行跳槽必看问题解答

热门文章

  1. python刘卫国答案第二_Homepages related
  2. 【机器学习】数据预处理 整理
  3. ActionSheet样式UIAlertController的正确使用
  4. Android 根据屏幕大小设置字体
  5. Linux系统打开文件命令
  6. 全国首档国货社交综艺《国货潮起来》,有了线下快闪店
  7. notes-JavaScript-JavaScript极速入门_玉女心经系列 网址:http://www.php.cn
  8. 用matlab绘制信源熵函数曲线,绘制信源熵函数曲线.doc
  9. 千万不要和一种编程语言厮守终生
  10. Gitee 上优秀的后台管理系统