MySQL数值类型溢出的处理方法

  

来,考考大家一个问题,在MySQL中当某一列设置为int(0)时会发生什么?

  

为了演示这个问题,我们先要创建一个表

        删除表如果存在“na”;   创建表“na”(   n1 INT (0) NOT NULL默认“0”,   n2 INT (11) NOT NULL默认' 0 '   );      

然后我们使用下面的语句往na表中插入一些数据

        mysql>插入“na”值(520520),(5201314,5201314);   查询好,2行影响(0.02秒)   记录:2副本:警告:0      

最后我们读取出来看看

        mysql>SELECT * FROM na;   + - - - - - - - - - - - - - - - - - - - - - - - - +   | n1 | n2 |   + - - - - - - - - - - - - - - - - - - - - - - - - +   | 520 | 520 |   | 5201314 | 5201314 |   + - - - - - - - - - - - - - - - - - - - - - - - - +   2行集(0.00秒)      

对的,好像什么都不会发生,没什么问题才是对的,我就怕有什么问题…哈哈

  

我们这一章节来讲讲整型溢出问题。

  


  

  

当MySQL在某个数值列上存储超出列数据类型允许范围的值时,结果取决于当时生效的SQL模式

  
      <李>如果启用了严格的SQL模式,则MySQL会根据SQL标准拒绝带有错误的超出范围的值,并且插入失败李   <李>如果没有启用任何限制模式,那么MySQL会将值裁剪到列数据类型范围的上下限值并存储   
        <李>当超出范围的值分配给整数列时,MySQL会存储表示列数据类型范围的相应端点的值   <李>当为浮点或定点列分配的值超出指定(或默认)精度和比例所隐含的范围时,MySQL会存储表示该范围的相应端点的值   
      李   
  

这个,应该很好理解吧?

  

我们举一个例子,假设t1表的结构如下

        创建表t1 (   i1非常小的整数,   i2非常小的整数无符号   );      

如果启用了严格的SQL模式,超出范围会发生一个错误

        mysql>设置sql_mode=按场?——首先设置严格模式   mysql>插入t1 (i1、i2)值(256、256);   错误1264 (22003):i1的范围值列在第一行   mysql>SELECT * FROM t1;   空集(0.00秒)      

当严格模式被禁,用值可以插入,但会被裁剪,并且引发一个警告

        mysql>设置sql_mode=";——禁用所有模式   mysql>插入t1 (i1、i2)值(256、256);   mysql>显示警告;   + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +   | | | |代码级别信息   + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +   | 1264 | |警告范围值列“i1”行1 |   | 1264 | |警告范围值列在第1行|“i2”   + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +   mysql>SELECT * FROM t1;   + - - - - - - - - - - - - +   | i1和i2 | |   + - - - - - - - - - - - - +   | 127 | 255 |   + - - - - - - - - - - - - + +      

如果未启用严格的SQL模式,对于改变表,数据加载INFILE、更新和多行插入等语句会由于裁剪而发生的列分配转换并且引发一个警告。

  

而如果启用了严格模式,这些语句会直接失败,并且未插入或更改部分或全部值,具体取决于表是否为事务表和其他因素。

  

数值表达式求值过程中的溢出会导致错误,例如,因为最大的有符号长整型数字值是9223372036854775807,因此以下表达式会产生错误

        mysql>选择9223372036854775807 + 1;   错误1690(22003):长整型数字值的范围(9223372036854775807 + 1)的      

为了在这种情况下使操作成功,需要将值转换为无符号

        mysql>选择演员(9223372036854775807无符号)+ 1;   + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +   |(9223372036854775807无符号)+ 1 |   + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +   | 9223372036854775808 |   + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +      

从另一方面说,是否发生溢出取决于操作数的范围,因此处理前一个表达式的另一种方法是使用精确值算术,因为十进制值的范围大于整数

MySQL数值类型溢出的处理方法