MySQL的表达式计算、运算符(算术/比较/逻辑/位)、类型转换、MySQL如何处理无效数据值 | 您所在的位置:网站首页 › mysql模式匹配运算符包括什么 › MySQL的表达式计算、运算符(算术/比较/逻辑/位)、类型转换、MySQL如何处理无效数据值 |
MySQL的表达式计算、运算符(算术/比较/逻辑/位)、类型转换、MySQL如何处理无效数据值
原创
董哥的黑板报 2022-03-25 15:51:39 博主文章分类:MySQL ©著作权 文章标签 MySQL运算符 字符串 运算符 mysql 文章分类 代码人生 ©著作权归作者所有:来自51CTO博客作者董哥的黑板报的原创作品,请联系作者获取转载授权,否则将追究法律责任 一、表达式表达式包含子项和运算符,并且经过计算可以产生具体值。子项可以包含值,如常数 、函数调 用、表列引用,以及标量子査询。这些值可以用不同种类的运算符(如算术运算符或比较运算符)组合在一起,表达式的子项可以用括号进行分组。绝大部分情况下,表达式都是出现在输出列的列表里,以及SELECT语句的WHERE子句里。例如,下面是一个查询语句:SELECT CONCAT(last_nam, ',', first_name), TIMESTAMPDIFF(YEAR, birth, death)FROM presidentWHERE birth > '1900-1-1' AND DEATH IS NOT NULL;每一个选择值都代表着一个表达式,与WHERE子句的内容一样。表达式也可以出现在DELETE和UPDATE语句的WHERE子句里、INSERT语句的VALUE()子句里等。当MySQL遇到表达式时,它会计算这个表达式,并产生一个结果。例如,表达式(4*3) DIV (4-2)的计算结果为6。表达式的计算过程可能涉及类型转换。例如,当数字用在需要DATE值的上下文中时,MySQL会把960821这样的数字转换成日期值'1996-08-21'。二、编写表达式表达式可以很简单,甚至允许只为一个常量,如数字0和字符串'abc'。使用函数表达式可以使用函数调用。有些函数带有实参 (即括号里的值),有些则没有。函数的多个实参之间应该用逗号隔开。在调用内建函数时,它的参数之间允许出现空格。但在函数名和紧随其后的左括号之间 不允许出现空格,因为MySQL的解析器可能会错误地解释函数名。常见的后果即是报语句出错。不过,通过启用SQL的IGNORE_SPACE模式,可以让MySQL允许内建函数名的后面出现空格,但这又会造成把函数名视为保留字的问题 。表达式里可以包含对表列的引用。对于最简单的情形,当可以根据上下文清楚地知道列所属的那个表时,只需给出该列的名字即可。在下面的两条SELECT语句里,由于它们都只用到了一个表,所以尽管这两条语句里的列名完全一样,但这些列引用不会产生歧义:SELECT last_name, first_name FROM president;SELECT last_name, first_name FROM member;如果还不清楚应该使用哪个表,则需要在列名的前面加上正确的表名进行限定。如果无法知道应该使用哪一个数据库 ,则需要在表名前面加上数据库名进行限定。即使在不会产生歧义的上下文里,也可以使用这种更为具体的限定形式,以便看起来更加明确:SELECT president.last_name, president.first_name, member.last_name, member.first_nameFROM president INNER JOIN memberWHERE president.last_name = member.last_name;关于限定符的更多信息请参考在表达式里,标量子査询可以用于提供单个值。这种子査询必须用括号括起来:SELECT * FROM president WHERE birth = (SELECT MAX(birth) FROM president);最后,可以根据所有这些类型的值 (常量、函数调用、列引用和子査询)组合成各种更加复杂的表达式。三、运算符类型四、运算符优先级当MySQL计算表达式时,其中的运算符决定了表达式中子项的分组顺序。有些运算符拥有较高的优先级,也就是说,它们会先于其他运算符进行计算。例如,乘法和除法高于加法和减法的优 先级。下面两个表达式是等价的,因为和“DIV”都会在“+”和之前进行计算:下面按优先级从高到低的顺序列出了各个运算符。其中:处于同一行的运算符拥有相同的优先级。优先级高的运算符会在优先级低的运算符之前进行计算。优先级相同的运算符则按从左至右的顺序依次进行计算。根据SQL模式或MySQL的版本差异,有些运算符具有不同的优先级顺序。要改写运算符的优先级,更改表达式子项的计算顺序,可以使用括号:五、表达式里的NULL值在表达式里使用NULL值时,要小心,因为其结果往往会出乎你的意料。下面这些指南能帮助你 避免意外情况的发生。当把NULL用作算术运算符或位运算符的操作数时 ,其计算结果皆为NULL:当把NULL与逻辑运算符一起使用时 ,除非其计算结果可以确定,否则其结果皆为NULL:当把NULL用作比较运算符或模式匹配运算符的操作数时 ,其计算结果皆为 NULL。不过 ,运 算符、IS NULL和IS NOT NULL例外,因为它们都是专门用于处理NULL值的:当把NULL用作函数参数时,函数通常会返回NULL。不过,那些专门用于处理NULL参数的函数 例外。例如,IFNULL()便可以处理NULL参数,并且会根据具体情况返回真值或假值。 另外,STRCMP()期望的是非NULL参数;如果把NULL作为参数传递给它,那么它返回的结果将为 NULL,而不是真值或假值。在排序运算中,NULL值会一起排序:当按升序排序时,它们会出现在最前面。当以降序排序时 ,会出现在最后面。六、类型转换只要某个值的类型与上下文所要求的类型不相符,MySQL就会根据操作的类型自动进行类型转 换 。发生类型转换的场合有以下几种:把操作数转换成适合运算符计算的相应类型。把函数参数转换成函数所期望的类型。把某个值转换成适合于存储在列里的另一种类型。另外,还可以利用类型转换运算符或函数来完成显式类型转换。可以根据系统变量character_set_connection和collation_connection所指定的字符集和排序规则 ,将数字转换成字符串或时态值。只有character_set_connection为binary时 ,转换结果才会是一个二进制串;否则,结果为非二进制串。(在MySQL 5.5.3之前,数字转换为字符串,总是会 得到一个二进制串)。演示案例下面这个表达式涉及一个隐式类型转换。它由一个加法运算符(+)和两个操作数(1和'2’)构成:1 + '2'由于这两个操作数的类型不一致(一个是数字,另一个是字符串),因此MySQL会对它们当中的某一个进行类型转换,以使它们的类型一致。但是,应该转换哪一个呢?在本例里,+是一个数字运算符,所以MySQL会要求两个操作数 都是数字类型,因此会把字符串'2'转换为数字2。然后表达式的计算结果为3。演示案例下面来看另一个示例。CONCAT()函数能够把多个字符串连接成一个更长的字符串。不管参数是什么类型,此函数都会把它们当作字符串来处理。当把一组数字传递给CONCAT()时,它会先把它们转换成字符串,然后再返回连接后的结果:# '123456'CONCAT(1,23,456)如果对CONCAT()函数的调用又属于某个更大的表达式,那么可能会发生进一步的类型转换。请看下面这个表达式及其结果:首先,C0NCAT(1,2,3)会返回字符串'123'。接着,'123'/10会转换成123/10。因为相除是一个算术运算符,此表达式的结果为12.3。由于REPEAT()函数需要的重复次数是一个整数 ,所以这个结果会四舍五入为整数 12。最后,REPEAT('X',I2)会把字符串'X'重复12次。# 'XXXXXXXXXXXX'REPEAT('X', CONCAT(1,2,3)/10)如果CONCATO的所有参数都是非二进制串,那么其结果也将是一个非二进制串。如果有参数为二进制串,那么其结果将是一个二进制串。其中,数字参数会像前面所讨论的那样 转换为字符串,然后应用前面的这些规则 。记住,默认情况下,MySQL会尽量把值转换为表达式所需要的类型,而不是产生错误。根据具体上下文的不同,MySQL会让值在三种通用类别(即数字、字符串、日期/时间)之间进行转换。不过,值并不是总能从一种类型转换成另外一种类型。如果某个值在类型转换后,看起来并不像目标类型的合法值,那么这个转换就是失败的:例如,把看起来并不像数字的某个值(如字符串'abc')转换为数字类型,那么最终得到的结果将为0。如果某个看起来并不像日期或时间的值转换为日期或时间类型,那么最终得到的结果将为该类型的“零”值。例如, 把字符串'abc'转换成日期类型,则得到的结果为“零”日期:'0000-00-00'。另外,由于任何值都可以处理成字符串,因此把一个值转换成字符串,在通常情况下都不会有问题。在数据输入操作期间,为防止把非法值转换成最相近的合法值,可以启用严格模式,以便把此类 问题当作错误报告出来 。更多相关细节可以参考后面"数据类型之处理无效值"文章。MySQL还会执行某些微小的类型转换。见下面介绍如果在整数上下文中使用浮点数值,那么浮点数值会被转换(通过四舍五入)。反之亦可,整数可以毫无问题地当作浮点数来使用。除非上下文明确地表明需要一个数字,否则十六进制常量会被当作二进制串来对待。在字符串上下文里,每两个十六进制数字会被转换成一个字符,最终结果将为一个字符串,如下列示例所示:对于比较操作中的十六进制常量,上下文会根据具体情况来确定是把它当成二进制串,还 是把它当成数字。下面的表达式会把操作数当作二进制串,并按字节进行比较。下面的表达式比较的是一个十六进制常量和一个数字,因此为了进行比较,该常量会先转换成数字。下面的表达式执行的是二进制串的比较。左操作数的第一个字节值比右操作数的第一个字节值小,因此结果为假。在了面的表达式里,右操作数中的十六进制常量会被转换成一个数字,因为那是个算术运 算。接着,为完成比较 ,左操作数也会转换成一个数字。最后,由于0xee00(60928)在数 字上大于0xff(255),所以最终的结果为真。使用字符集引导符或CONVERT(),可以把十六进制常量强制转换成一个非二进制串:有些运算符会把操作数强制转换成它所期望的类型,而不管该操作数原来是什么类型。以算术运算符为例。它们期望的是数字,因此其操作数都会进行相应的转换:对于“字符串到数字”的转换 ,只是字符串里的某个地方包含一个数字还远远不够。MySQL 并不会检査整个字符串,以期望找到某个数字;它只会检查字符串的开头 。如果字符串的开头部分不是数字,那么转换的结果即为0。MySQL的“字符串到数字”的转换规则,适用于把看起来像数字的字符串转换为数字值:不过,这种转换对于看起来像十六进制常量的字符串不起作用。只有使用前导“0”的才可转换:位运算符甚至比算术运算符还严格。它们不仅要求操作数得是数字,而且还要求它们是整数(根据情况进行相应的类型转换)。这意味着,对于像0.3这样的小数,即使它为非零值,也不会被当 成逻辑真值。因为当它转换成整数时,所得结果为0。在下面几个表达式里,只有那些值 大于1的操作数才会被认为是逻辑真值:模式匹配运算符希望操作的是字符串。这意味着,可以把MySQL的模式匹配运算符用于数字,因为在査找匹配的过程中,它会把这些数字转换成字符串!大小比较运算符( 赞 收藏 评论 分享 举报上一篇:C++:26---算术、关系、逻辑运算模板(functional头文件) 下一篇:项目(百万并发网络通信架构)12.2---内存管理之(为服务端添加智能指针) |
CopyRight 2018-2019 实验室设备网 版权所有 |