跟我一起学习MySQL技术内幕(第五版):(第三章学习日记16)

~
考试月过去了,现在正在支教~全力补上
~

3.5.2类型转换

只要某个值的类型与上下文所要求得类型不相符,MySQL会根据操作符的类型自动进行类型转化。发生类型性转换的场合有以下几种

1、把操作符数转换为适合运算符计算的相应类型。
2、把函数参数转换成函数所期望的类型
3、把某个值转换为适合于存储在列里的另一种类型。
另外,还可以使用类型转换运算符或函数来完成显式类型转换。

可以根据系统变量character_set_connection 和collation_connection所指定的字符集和排序规则,将数字转换成字符串或时态值。只有character_set_connection位binary时,转换结果才会是一个二进制串,否则,结果为非二进制串。

1+  '2'      ->3

+是一个 数字运算符,所以MySQL会要求两个操作数都是数字类型,因此会把字符串‘2’转换为数字2

repeat('x',concat(1,2,3)/10)  ->'xxxxxxxxxxxx'

首先concat(1,2,3)会返回字符串‘123’。接着‘123’/10会转换为123/10,因为相除是一个算术运算符。此表达式的结果为12.3。由于repeat()函数需要的重复次数是一个整数,所以这个结果四舍五入为12。最后会重复‘x’12遍。

如果concat()的所有参数都是非二进制串,那么其结果也将是一个非二进制串。如果有参数为二进制串,那么其结果将是一个二进制串。其中,数字参数会转换为字符串,然后应用之前的规则。

默认情况下,MySQL会尽量把值转换为表达式所需要的类型,而不是产生错误。根据具体上下文的不同,MySQL会让值在三种通用类别(数字,字符串,日期/时间)进行转换。不过,值并不是总能从一种类型转换为另一种类型。如果某个值 在类型转换后,看起来并不像目标类型的合法值,那么这个转换就是失败的。最终得到的结果将为该类型的零值。

在数据输入期间,为防止把非法值转换成最近的合法值,可以启用严格模式,以便把此类问题当做错误报告出来。

MySQL还会执行某些微小的类型转换。如果在整数上下文中使用浮点数值,那么浮点数值会被转换。整数可以毫无问题的当做浮点数来使用。

除非上下文明确地表明需要一个数字,否则十六进制数常量会被当作二进制串来对待。在字符串上下文中,每两个十六进制数字会被转换为一个字符,最终结果为一个字符串

0x61         ->'a'
0x61 + 0     ->97
X'61'        ->'a'
X'61'+0      ->97
concat(0x61)     ->'a'
concat(0x61 + 0) ->'97'
concat(X'61')    ->'a'
concat(X'61')    ->'97'

对于比较操作中的十六进制常量,上下文会根据具体情况来确定是把它当成二进制串还是数字。

1.下面的表达式会把操作数当成二进制串,并按字节进行比较
    0x0d0a  = '\r\n'                   ->1

2.下面的表达式比较的是一个十六进制常量和一个数字,因此为了进行比较,该常量会先转换成数字
    0x0a    = 10                       ->1
3.下面的表达式执行的是二进制串的比较。左操作数的第一个字节值比右操作数小,因此结果为假
    0xee00  > 0xff                     ->0
4.在下面的表达式里,右操作数中的十六进制常量会被转化为一个数字,因为那是个算术运算。接着,为完成比较,左操作数也会转化为一个数字。最后,由于0xee00(60928)在数字上大于0xff(255),所以最终结果为真。
    0xee00  > 0xff+0                   ->1
使用字符集引导符或convert(),可以把十六进制常量强制转化成一个非二进制串
    0x61    ->'a'                      ->'a'
    0x61    ->'A'                      ->0
    _latin1 0x61 = 'A'                 ->1
    convert (0x61 using latin1) ='A'   ->1
有些运算符会把操作数强制转化为它所期望的类型,而不管这些操作数原来是什么类型。
    3+4         ->7
    '3' + 4     ->7
    '3' +'4'    ->7
对于"字符串到数字"的转换,只是字符串里的某个地方包含一个数字还远远不够。MySQL并不会检查整个字符串,以期望找到某个数字;它只会检查字符串的开头部分是不是数字。如果不是,转换的结果即为0。
    '1973-2-4'  +0    ->1973
    '12:14:01'  +0    ->12
    '23-skidoo' +0    ->23
    '-23-skidoo'+0    ->-23
    'carbon-14' +0    ->0
MySQL的"字符串到数字"的转换规则,适用于把看起来像数字的字符串转换为数字值:
    '-428.9'+0    ->428.9
    '3E-4'  +0    ->0.0003
不过,这种转换对于看起来像十六进制敞亮的字符串不起作用,只有使用前导"0"的才可以转换
    '0xff' +0     ->0
位运算符甚至比算术运算符还严格。它们不仅要求操作数时数字,而且还要求它们是整数(根据情况进行相应的类型转换)这意味着,对于像0.3这样的小数,即使它为非零值,也不会被当成逻辑真值。因为当它转换成整数时,所得结果为零。在下面几个表达式里,只有那些值大于1的操作数才会被认为是逻辑真值:
    0.3|.04       ->0
    1.3|.04       ->1
    0.3&.04       ->0
    1.3&.04       ->0
    1.3&1.04      ->1
模式匹配运算符希望操作的是字符串。这意味着,可以把MySQL的模式匹配运算符用于数字,因为在查找匹配的过程中,它会把这些数字转换成字符串
    12345 like   '1%'       ->1
    12345 regexp '1.*5'     ->1
大小比较运算符(<、<=、=等)跟上下文密切相关,也就是说,他们会根据操作数的类型来进行计算。下列表达式会比较两个操作数的数字大小,因为他们都是数字:
    2<11        ->1
下列表达式涉及的操作符都是字符串,因为它们会按词法进行比较:
    '2'<'11'    ->1
在下列表达式里,两个操作数的类型各不相同,因此MySQL会按数字方式对他们进行比较。于是,这两个表达式的结果都为真:
    '2'<11      ->1
    2<'11'      ->1

在进行比较运算时,MySQL会根据需要按以下规则对操作数进行类型转换。

1.除<=>运算符以外,所有涉及NULL值得比较结果都为NULL。(另外,<=>与=很像,只是NULL<=>NULL的结果为真,而NULL=NULL的结果为NULL)
2.如果两个操作数都是字符串,那么她们将按字符串进行词法比较。对于二进制串,会按字节逐个比较各个对应字节的数值。对于非二进制串,会使用表示字符串的字符集的排序序列,逐个字符的进行比较。如果字符串使用了不同的字符集,那么这个比较可能导致错误或者产生毫无意义的结果。对于非二进制串和二进制串之间的比较,按二进制串方式进行。
3.如果两个操作数都是整数,那么她们将按整数方式进行数字比较。
4.与数字进行比较的十六进制常量,会按二进制串进行比较。
5.除in()以外,如果有一个操作数为timestamp或datetime,而另一个操作数为常量,那么两个操作数会按timestamp值进行比较。这种做法很适合于各种ODBC应用程序的比较操作。
6.如果有一个操作数为小数,而另一个操作数为小数或整数,那么两个操作数会按小数进行比较;否则,按啥UN高精度浮点值进行比较。
7.除上述情况以外,比较操作中的操作数都将按照双精度浮点值进行数字比较。请注意,字符串与数字之间的比较也属于这种情况。字符串将被转换为一个双精度数,如果字符串看起来不像数字,那么转换结果将为0。例如,'14.3'将被黄钻华为14。3但'L4.3'会被转化为0。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值