ERROR 1690(22003):BIGINT UNSIGNED值超出范围

时间:2014-09-11 12:34:02

标签: mysql casting

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

2 个答案:

答案 0 :(得分:0)

由于您使用的是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

或者如果您需要值&gt; 127使用:

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

答案 1 :(得分:0)

默认情况下,MySQL不再(不再)通过减去无符号操作数产生带符号结果,也不会产生混合符号乘法。

您必须启用the MySQL mode MODE_NO_UNSIGNED_SUBTRACTION才能恢复减法的旧(非常合理)默认行为。似乎没有用于乘法的并行促销模式。

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

除此之外:类型的宽度无关紧要。在我第一次遇到我认为它只会影响BIGINT操作数。因为没有更宽的签名类型,并且大值无法正确表示,在这种情况下我会理解错误条件,但正如您所看到的,此错误一直发生到最小的整数类型(例如从TINYINT UNSIGNED列中拉出的值。)