BIGINT UNSIGNED value is out of range in 问题处理

现状描述

    今天,开发人员找到我,订单报错,分析后定位到一条sql:

SELECT

  忽略内容,

    t.amount-

    (SELECT

      COUNT(gd.subs_id)

    FROM

      隐藏表名 AS gd

    WHERE gd.order_id = t.order_id

      AND gd.contract_type = 57

      AND gd.buyorsell = 1

      AND gd.status NOT IN (- 2, - 3)) AS amount_left_s

  FROM

    原表名 t

  WHERE t.domain_no = 2300

    AND t.order_id = 61083

手动在从库执行此条sql,果然报错:BIGINT UNSIGNED value is out of range in(xxx)


解决过程

1.从报错来看,是字段类型超过限制导致,因此将计算字段分拆,看能否执行通过:

 t.amount-
(SELECT

      COUNT(gd.subs_id)

    FROM

      隐藏表名 AS gd

    WHERE gd.order_id = t.order_id

      AND gd.contract_type = 57

      AND gd.buyorsell = 1

      AND gd.status NOT IN (- 2, - 3)) AS amount_left_s

改为

 t.amount ,

(SELECT

      COUNT(gd.subs_id)

    FROM

      隐藏表名 AS gd

    WHERE gd.order_id = t.order_id

      AND gd.contract_type = 57

      AND gd.buyorsell = 1

      AND gd.status NOT IN (- 2, - 3)) AS amount_left_s

两个字段,结论是可以查询出结果,且值如下图:


两值相减为负数,符合报错的含义,将此结果反映给开发,开发人员认为是产品逻辑的问题,去重写逻辑了。

2.虽然业务上此问题解决了,但是技术上,就报错本身,可以再深入研究下。我创建了一张表:


执行如下语句发现报错:

select a,b,a-b from t;

错误代码: 1690

BIGINT UNSIGNED value is out of range in '(`aaa`.`t`.`a` - `aaa`.`t`.`b`)'

做如下的表结果更改仍然报错:


说明只要参与计算的字段存在unsigend设置,就会执行失败。若是两个字段都取消unsigned设置,则会查询出结果:(SELECT a,b,a-b FROM t;)


3.反映到上面业务上的情况,假设允许最终结果为负值,则有如下两种方案:

(1)后一个字段为子查询,且结果为count,因此只需要更改前面字段类型为signed即可。将t.amount字段类型修改为signed。

(2)当业务不允许ddl表时,可以修改sql语句,临时转换字段类型进行处理,以我自建表为例,刚才语句可以做如下改写:

SELECT a,b,a-b FROM t;

修改为

select a,b,cast(a as signed)-cast(b as signed) from t;

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容