MySQL中隐式转换方法

隐式转化规则

官方文档中关于隐式转化的规则是如下描述的:

If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe equality comparison operator. For NULL NULL, the result is true. No conversion is needed.

If both arguments in a comparison operation are strings, they are compared as strings.

If both arguments are integers, they are compared as integers.

Hexadecimal values are treated as binary strings if not compared to a number.

If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.
A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.

If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.

In all other cases, the arguments are compared as floating-point (real) numbers.

翻译为中文就是:

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

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

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

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

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

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

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

问题描述

where 条件语句里,字段属性和赋给的条件,当数据类型不一样,这时候是没法直接比较的,需要进行一致转换

默认转换规则是:

不同类型全都转换为浮点型(下文都说成整型了,一个意思)

如果字段是字符,条件是整型,那么会把表中字段全都转换为整型(也就是上面图中的问题,下面有详细解释)

转换总结

字符转整型

字符开头的一律为0

数字开头的,直接截取到第一个不是字符的位置

电子手机配件网站源码1.0 电子手机配件网站源码1.0

电子手机配件网站源码是一个响应式的织梦网站模板,软件兼容主流浏览器,且可以在PC端和手机端中进行浏览。模板包含安装说明,并包含测试数据。本模板基于DEDECms 5.7 UTF-8设计,需要GBK版本的请自己转换。模板安装方法:1、下载最新的织梦dedecms5.7 UTF-8版本。2、解压下载的织梦安装包,得到docs和uploads两个文件夹,请将uploads里面的所有文件和文件夹上传到你的

电子手机配件网站源码1.0 0 查看详情 电子手机配件网站源码1.0

时间类型转换

按照字符串进行截取

23:12:13 -> 2023-12-13(这个后文有讨论)

对于不符合的时间值,如10:12:32等,会变为 0000-00-00 或为 空

cast函数只能转datetime,不能转timestamp

如果按照timestamp来理解,因为timestamp是有范围的(‘1970-01-01 00:00:01.000000′ to’2038-01-19 03:14:07.999999’),所以只能是2023年,而不能是1923年

直接截取time字段

直接截取date字段

无意义,直接为 00:00:00

追加 00:00:00

date 转 datetime 或者 timestamp

date 转 time

datetime 或者 timestamp 转 date

datetime 或者 timestamp 转 time

time 转 datetime 或者 timestamp

time和datetime转换为数字时,会变为双精度,加上ms(版本不同不一样)

案例分析

表结构,name字段有索引

-- 注意name字段是有索引的CREATE TABLE `t3` (  `id` int(11) NOT NULL,  `c1` int(11) NOT NULL,  `name` varchar(100) NOT NULL DEFAULT 'fajlfjalfka',  KEY `name` (`name`),  KEY `id` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.00 sec)
-- 模拟线上一个隐式转换带来的全表扫面慢查询-- 发生隐式转换xxxx.test> select * from t3 where name = 0;+----+----+-------------+| id | c1 | name        |+----+----+-------------+|  1 |  2 | fajlfjalfka ||  2 |  0 | fajlfjalfka ||  1 |  2 | fajlfjalfka ||  2 |  0 | fajlfjalfka |+----+----+-------------+4 rows in set, 4 warnings (0.00 sec)-- 上述SQL执行计划是全表扫描,扫描后,字符转整型,都是0,匹配上了条件,全部返回xxxx.test> desc select * from t3 where name = 0;+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+|  1 | SIMPLE      | t3    | ALL  | name          | NULL | NULL    | NULL |    4 | Using where |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+1 row in set (0.00 sec)-- 加上单引号后,是走name索引的,非全表扫描xxxx.test> desc select * from t3 where name = '0';+----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra                 |+----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+|  1 | SIMPLE      | t3    | ref  | name          | name | 102     | const |    1 | Using index condition |+----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+1 row in set (0.00 sec)-- 走索引,没返回xxxx.test>  select * from t3 where name = '1';Empty set (0.00 sec)

解释

如果条件写0或者1,会进行全表扫面,需要把所有的name字段由字符全都转换为整型,再和0或者1去比较。由于都是字母开头的字符,会全都转为为0,返回的结果就是所有行。

那有人问了,为什么不把条件里的 0 自动改成 '0' ?见下文。

转换举例

-- 字符开头,直接是0xxxx.test> select cast('a1' as unsigned int) as test ;+------+| test |+------+|    0 |+------+1 row in set, 1 warning (0.00 sec)xxxx.test> show warnings;+---------+------+-----------------------------------------+| Level   | Code | Message                                 |+---------+------+-----------------------------------------+| Warning | 1292 | Truncated incorrect INTEGER value: 'a1' |+---------+------+-----------------------------------------+1 row in set (0.00 sec)-- 开头不是字符,一直截取到第一个不是字符的位置xxxx.test> select cast('1a1' as unsigned int) as test ; +------+| test |+------+|    1 |+------+1 row in set, 1 warning (0.00 sec)xxxx.test> select cast('123a1' as unsigned int) as test ;+------+| test |+------+|  123 |+------+1 row in set, 1 warning (0.00 sec)-- 直接按照字符截取,补上了20(不能补19)xxxx.test> select cast('23:12:13' as datetime) as test ;+---------------------+| test                |+---------------------+| 2023-12-13 00:00:00 |+---------------------+1 row in set (0.00 sec)-- 为什么不能转换为timestamp,没搞清楚,官方文档给的转换类型里没有timestamp。如果是这样的话,上面的datetime就不好解释为什不是1923了。难道是检测了当前的系统时间?xxxx.test> select cast('23:12:13' as timestamp) as test ;    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'timestamp) as test' at line 1-- 这个时间无法转换成datetimexxxx.test> select cast('10:12:32' as datetime) as test ;         +------+| test |+------+| NULL |+------+1 row in set, 1 warning (0.00 sec)xxxx.test> show warnings ;+---------+------+--------------------------------------+| Level   | Code | Message                              |+---------+------+--------------------------------------+| Warning | 1292 | Incorrect datetime value: '10:12:32' |+---------+------+--------------------------------------+1 row in set (0.00 sec)-- 5.5版本下,时间转字符,会增加msxxxx.(none)> select version();+------------+| version()  |+------------+| 5.5.31-log |+------------+1 row in set (0.00 sec)xxxx.(none)> select CURTIME(), CURTIME()+0, NOW(), NOW()+0 ;+-----------+---------------+---------------------+-----------------------+| CURTIME() | CURTIME()+0   | NOW()               | NOW()+0               |+-----------+---------------+---------------------+-----------------------+| 15:40:01  | 154001.000000 | 2016-05-06 15:40:01 | 20160506154001.000000 |+-----------+---------------+---------------------+-----------------------+1 row in set (0.00 sec)-- 5.6 不会xxxx.test> select version();+------------+| version()  |+------------+| 5.6.24-log |+------------+1 row in set (0.00 sec)xxxx.test> select CURTIME(), CURTIME()+0, NOW(), NOW()+0 ;+-----------+-------------+---------------------+----------------+| CURTIME() | CURTIME()+0 | NOW()               | NOW()+0        |+-----------+-------------+---------------------+----------------+| 15:40:55  |      154055 | 2016-05-06 15:40:55 | 20160506154055 |+-----------+-------------+---------------------+----------------+1 row in set (0.00 sec)

为什么不把 where name = 0 中的 0 转换为 '0'

如果是数字往字符去转换,如 0 转’0’,这样查询出来的结果只能是字段等于 ‘0’,而实际上,表里的数据,如’a0’,’00’,这其实都是用户想要的0,毕竟是用户指定了数字0,所以MySQL还是以用户发出的需求为准,否则,’00’这些都不会返回给用户。

总结

有了上面的内容,开头的问题是可以解释了。

上图的例子,是不是可以用来绕过身份验证?

补充

-- 上面遗留的问题,跟系统时间并没有关系。怀疑虽然指定的是datetime,但是内部还是按照timestamp去做的。mysql> select now();+---------------------+| now()               |+---------------------+| 1999-08-03 14:16:50 |+---------------------+1 row in set (0.00 sec)mysql> select cast('23:12:13' as datetime) as test ;+---------------------+| test                |+---------------------+| 2023-12-13 00:00:00 |+---------------------+1 row in set (0.00 sec)

以上就是MySQL中隐式转换方法 的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1041028.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月2日 04:41:54
下一篇 2025年12月2日 04:42:15

相关推荐

  • 网络进化!

    Web 应用程序从静态网站到动态网页的演变是由对更具交互性、用户友好性和功能丰富的 Web 体验的需求推动的。以下是这种范式转变的概述: 1. 静态网站(1990 年代) 定义:静态网站由用 HTML 编写的固定内容组成。每个页面都是预先构建并存储在服务器上,并且向每个用户传递相同的内容。技术:HT…

    2025年12月24日
    000
  • 为什么多年的经验让我选择全栈而不是平均栈

    在全栈和平均栈开发方面工作了 6 年多,我可以告诉您,虽然这两种方法都是流行且有效的方法,但它们满足不同的需求,并且有自己的优点和缺点。这两个堆栈都可以帮助您创建 Web 应用程序,但它们的实现方式却截然不同。如果您在两者之间难以选择,我希望我在两者之间的经验能给您一些有用的见解。 在这篇文章中,我…

    2025年12月24日
    000
  • 如何通过纯CSS实现图片的放大缩小效果的方法和技巧

    如何通过纯CSS实现图片的放大缩小效果的方法和技巧 在现代的网页设计中,图片的展示和处理是非常重要的一部分。而图片的放大缩小效果可以为网站的视觉呈现增添趣味和交互性。在这篇文章中,我们将介绍如何通过纯CSS实现图片的放大缩小效果,并提供具体的代码示例。 使用transition属性实现平滑的过渡效果…

    2025年12月24日
    000
  • 利用CSS实现折叠内容面板特效的技巧和方法

    利用CSS实现折叠内容面板特效的技巧和方法 在网页设计中,折叠内容面板是一种非常常见的特效。通过点击或其他交互形式,隐藏或展示特定内容,以提供更好的用户体验。而利用CSS实现折叠内容面板特效,则是一种简单而有效的方法。本文将介绍一些实现这一特效的技巧和方法,并提供具体的代码示例。 使用checkbo…

    2025年12月24日
    000
  • css中的浏览器私有化前缀有哪些

    css中的浏览器私有化前缀有:1、谷歌浏览器和苹果浏览器【-webkit-】;2、火狐浏览器【-moz-】;3、IE浏览器【-ms-】;4、欧朋浏览器【-o-】。 浏览器私有化前缀有如下几个: (学习视频分享:css视频教程) -webkit-:谷歌 苹果 background:-webkit-li…

    2025年12月24日
    300
  • 如何利用css改变浏览器滚动条样式

    注意:该方法只适用于 -webkit- 内核浏览器 滚动条外观由两部分组成: 1、滚动条整体滑轨 2、滚动条滑轨内滑块 在CSS中滚动条由3部分组成 立即学习“前端免费学习笔记(深入)”; name::-webkit-scrollbar //滚动条整体样式name::-webkit-scrollba…

    2025年12月24日
    000
  • css如何解决不同浏览器下文本兼容的问题

    目标: css实现不同浏览器下兼容文本两端对齐。 在 form 表单的前端布局中,我们经常需要将文本框的提示文本两端对齐,例如: 解决过程: 立即学习“前端免费学习笔记(深入)”; 1、首先想到是能不能直接靠 css 解决问题 css .test-justify { text-align: just…

    2025年12月24日 好文分享
    200
  • css如何清除下划线?css清除下划线有哪些方法

    css怎么清除下划线?css去除下划线方法有哪些?很多人可能还不知道怎么操作,下面我们来讲解一下。在css中,我们可以使用text-decoration属性来表示下划线和删除线等样式,首先我们要了解一下text-decoration属性。 text-decoration属性一共有五个值,分别是non…

    2025年12月24日
    100
  • CSS如何实现任意角度的扇形(代码示例)

    本篇文章给大家带来的内容是关于CSS如何实现任意角度的扇形(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 扇形制作原理,底部一个纯色原形,里面2个相同颜色的半圆,可以是白色,内部半圆按一定角度变化,就可以产生出扇形效果 扇形绘制 .shanxing{ position:…

    2025年12月24日
    000
  • css如何让div居中?css实现div居中的方法

    如何让div水平居中?div怎么居中?相信很多人都会这样的疑问,本篇文章就讲解一下css如何让div居中?以及如何实现div居中的方法。 当我们浏览网页的时候,会发现一般网站的主体都是在页面的中间,并且居中显示在浏览器中的正中央,只要我们实现div居中条件和浏览器居中条件保存一致。 假如我们把最外层…

    2025年12月24日
    000
  • CSS如何设置滚动条样式?CSS设置滚动条样式方法

    现在很多项目中都用到了滚动条,而且在有的时候,用到的是模拟滚动条,很多大型邮箱都是利用css样式来设置的,那么css如何设置滚动条样式?css如何设置滚动条样式方法有哪些? 一、webkit下面的CSS设置滚动条 上面是滚动条的主要几个设置属性,还有更详尽的CSS属性 :horizontal:水平方…

    2025年12月24日
    000
  • 关于jQuery浏览器CSS3特写兼容的介绍

    这篇文章主要介绍了jquery浏览器css3特写兼容的方法,实例分析了jquery兼容浏览器的使用技巧,需要的朋友可以参考下 本文实例讲述了jQuery浏览器CSS3特写兼容的方法。分享给大家供大家参考。具体分析如下: CSS3充分吸收多年了web发展的需求,吸收了很多新颖的特性。例如border-…

    好文分享 2025年12月24日
    000
  • 网页添加CSS样式表的四种方法

    网页添加css样式表的四种方法,大家可以根据需要选择自己喜欢的方式。 一、使用STYLE属性: 将STYLE属性直接加在个别的元件标签里。 例如: 这种用法的优点 是可灵巧应用样式於各标签中,但是缺点则是没有整篇文件的『统一性』。 二、使用STYLE标签: 将样式规则写在…标签之中。 复…

    好文分享 2025年12月24日
    000
  • CSS布局自适应高度终极方法

    这篇文章主要介绍了关于CSS布局自适应高度终极方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 我们排版的最终目的是让程序员能快速绑定,最终的真实数据能和效果图一样,但是我们经常在国字型页面里面碰到左右两列的高度不确定,这样我们必须要把两列的自己适应,请看解决方法 ,每列高度(事先…

    好文分享 2025年12月24日
    000
  • 让div撑满整个屏幕的方法(css)

    这篇文章主要介绍了关于让div撑满整个屏幕的方法(css),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 在body只有一个p的时候,可以通过这样的方式让p撑满整个屏幕。 1.给p设置定位。   复习一下——   css中position有五种属性:     static:默认值,没…

    好文分享 2025年12月24日
    000
  • 使用CSS给图片添加阴影的方法

    一般我们可以使用背景图的方式给图片添加阴影,但对于不固定尺寸的图片如何实现呢?我们可以采取“视觉欺骗大法”——定义渐变边框来实现: [code] on_all”> 一般我们可以使用背景图的方式给图片添加阴影,但对于不固定尺寸的图片如何实现呢?我们可以采取“视觉欺骗大法”——定义渐变…

    好文分享 2025年12月24日
    000
  • 360浏览器兼容模式的页面显示不全怎么处理

    这次给大家带来360浏览器兼容模式的页面显示不全怎么处理,处理360浏览器兼容模式页面显示不全的注意事项有哪些,下面就是实战案例,一起来看一下。  由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览。基于IE的内核用于兼容网银、旧版网站。以360的几款浏览…

    好文分享 2025年12月24日
    000
  • css实现圆角三角形的方法

    本文主要和大家介绍了css实现带圆角三角型的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 前言 目标实现效果图如下: 实现 .triangle{ display: inline-block; font-size: 0; overf…

    2025年12月24日 好文分享
    000
  • CSS有几种实现三栏布局的方法

    这次给大家带来CSS有几种实现三栏布局的方法,CSS实现三栏布局的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 其实不管是三栏布局还是两栏布局都是我们在平时项目里经常使用的,也许你不知道什么事三栏布局什么是两栏布局但实际已经在用,或许你知道三栏布局的一种或两种方法,但实际操作中也只会依赖那…

    好文分享 2025年12月24日
    000
  • CSS定制文本省略的方法

    这次给大家带来CSS定制文本省略的方法,CSS定制文本省略的注意事项有哪些,下面就是实战案例,一起来看一下。 WeTest导读 拿到设计MM的设计稿,Oh NO,点点点后面又双叒叕加内容了,弹丸之地,劳心费神啊!!可怜我们UI开发GG每次苦口婆心说,微臣不是不做,是办不到啊!很是愧疚。而现在,自从用…

    2025年12月24日 好文分享
    000

发表回复

登录后才能评论
关注微信