【问题标题】:ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in错误 1690 (22003):BIGINT UNSIGNED 值超出范围
【发布时间】:2014-11-05 09:51:21
【问题描述】:

MySQL 版本:5.5.38-0ubuntu0.14.04.1

表结构:

CREATE TABLE `route_points2` (
 `dist` tinyint(4) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

数据:1 行,dist 等于 200

Sql:

SELECT * FROM route_points2 WHERE -1*dist < 1;

错误:

ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(<cache>(-(1)) * `db_name`.`route_points2`.`dist`)'

为什么 mysql 将 -1*dist 强制转换为 BIGINT UNSIGNED

上面的错误可以通过将dist转换为SIGNED来解决:

SELECT * FROM route_points2 WHERE -1*CAST(dist AS SIGNED) < 1;

这很好用。

但是我不明白mysql为什么选择BIGINT UNSIGNED代替-1*dist

【问题讨论】:

  • 你可以避免CAST 使用类似的东西:SELECT * FROM `route_points2` WHERE -`dist` &lt; 1;
  • 这是一个简化的例子。在现实世界中,它不仅仅是符号反转。

标签: mysql casting


【解决方案1】:

由于您使用的是 UNSIGNED 数字,并且与 SIGNED 数字 (-1) 进行比较,mysql 需要将您的 UNSIGNED 转换为 SIGNED。我猜它选择 BIGINT 是为了能够应对所有可能的 INT。

MySQL 5.5 改变了行为,看看这个http://dev.mysql.com/doc/refman/5.5/en/out-of-range-and-overflow.html

要完成这项工作,请将您的表定义为:

CREATE TABLE `route_points2` (
 `dist` tinyint NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

或者如果您需要值 > 127,请使用:

CREATE TABLE `route_points2` (
 `dist` smallint NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

【讨论】:

    【解决方案2】:

    默认情况下,MySQL 不再(不再)从无符号操作数的减法中产生有符号的结果,也不会从混合符号乘法中产生。

    您必须启用the MySQL mode MODE_NO_UNSIGNED_SUBTRACTION 才能恢复旧的(相当合理的)减法默认行为。乘法似乎没有并行提升模式。

    正如您已经发布的那样,解决方案是在减法的两个操作数以及可能混合乘法中的任何无符号操作数上使用 CAST 运算符。

    除此之外:类型的宽度无关紧要。在我第一次遇到时,我认为它只会影响 BIGINT 操作数。由于没有更广泛的有符号类型可供选择,并且无法正确表示大值,我会理解这种情况下的错误情况,但正如您所看到的,此错误一直发生在最小的整数类型(例如从 TINYINT UNSIGNED 列中提取的值)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多