【问题标题】:ERROR 1690 (22003): BIGINT UNSIGNED value is out getting错误 1690 (22003):BIGINT UNSIGNED 值超出
【发布时间】:2018-11-27 11:46:07
【问题描述】:
SELECT alertid,
       ackuid,
       severity,
       ticketid,
       From_unixtime(display_ts)                           AS Detection_Time,
       From_unixtime(ack_ts)                               AS Ack_Time,
       Round(( ack_ts - display_ts ) / 60)                 AS MTTA_MINS,
       IF (Round(( ack_ts - display_ts ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM   alerts_test
WHERE  display_ts > Unix_timestamp(Now() - INTERVAL 26 day)
ORDER  BY From_unixtime(display_ts); 

错误 1690 (22003):BIGINT UNSIGNED 值超出范围 '(dba.DBA_IRIS_ALERTS.ack_ts - dba.DBA_IRIS_ALERTS.display_ts)'

如何解决这个错误?尤其是在这种情况下,它失败了。

round((ack_ts-display_ts)/60) as MTTA_MINS,
IF ( round((ack_ts-display_ts)/60) > 15, 1, 0) as SLA_MISSED

样本数据

+----------------------------------+-----------------+----------+-------------+---------------------+---------------------+-----------+------------+
| alertid                          | ackuid          | severity | ticketid    | Detection_Time      | Ack_Time            | MTTA_MINS | SLA_MISSED |
+----------------------------------+-----------------+----------+-------------+---------------------+---------------------+-----------+------------+
| xxxxxx                           | him            |        5 | NULL        | 2018-11-01 00:03:23 | 2018-11-01 00:06:18 |         3 |          0 |
| xxxxxx                           | him            |        5 | NULL        | 2018-11-01 00:11:08 | 2018-11-01 00:17:45 |         7 |          0 |

【问题讨论】:

  • 对这个错误有什么帮助吗?
  • 请在问题中添加一些示例数据。或者设置一个小提琴:db-fiddle.com 不看数据很难弄清楚。
  • 您添加到问题中的不是样本数据。因为,ack_tsdisplay_ts 列似乎存储了 Unix 时间戳(秒)值。您能否将CREATE TABLE 语句结果添加到问题中。执行SHOW CREATE TABLE alerts_test 并将此查询的结果发布到问题

标签: mysql


【解决方案1】:

来自Out-of-Range and Overflow Handling

整数值之间的减法,其中一个是 UNSIGNED 类型, 默认情况下产生无符号结果。如果结果会不然 一直为负,错误结果:

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'

所以,我认为 ack_ts 和/或 display_ts 列似乎代表 Unix 时间戳值,是在您的 CREATE TABLE 语句中使用 UNSIGNED 标志定义的(这很好,因为 Unix Timestamp 值只能是正数)。

因此,您减去UNSIGNED 类型的列,ack_ts - display_ts 的结果为负数。因此,您会遇到 ack_ts display_ts 的情况。

现在,有两种可能:

  1. 可能不会在寻找ack_ts display_ts的案例。

在这种情况下,您需要在查询中添加另一个 WHERE 条件:

SELECT alertid,
       ackuid,
       severity,
       ticketid,
       From_unixtime(display_ts)                           AS Detection_Time,
       From_unixtime(ack_ts)                               AS Ack_Time,
       Round(( ack_ts - display_ts ) / 60)                 AS MTTA_MINS,
       IF (Round(( ack_ts - display_ts ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM   alerts_test
WHERE  display_ts > Unix_timestamp(Now() - INTERVAL 26 day) AND 
       ack_ts >= display_ts   /* added one more condition to remove negative cases */
ORDER  BY From_unixtime(display_ts); 
  1. 您可以接受负值

在这种情况下,您需要将它们转换为SIGNED,以允许计算结果为负值:

SELECT alertid,
       ackuid,
       severity,
       ticketid,
       From_unixtime(display_ts)                           AS Detection_Time,
       From_unixtime(ack_ts)                               AS Ack_Time,
       Round(( CAST(ack_ts AS SIGNED) - CAST(display_ts AS SIGNED) ) / 60) AS MTTA_MINS,
       IF (Round(( CAST(ack_ts AS SIGNED) - CAST(display_ts AS SIGNED) ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM   alerts_test
WHERE  display_ts > Unix_timestamp(Now() - INTERVAL 26 day) 
ORDER  BY From_unixtime(display_ts); 

另一个选项是将sql_mode 设置为使用NO_UNSIGNED_SUBTRACTION。现在,您可以在设置模式后使用原始查询:

SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';

您可能无权在全局范围内更改此设置。因此,您可以在原始查询之前运行以下查询,以便仅针对特定客户端会话进行此更改。

SET SESSION sql_mode = 'NO_UNSIGNED_SUBTRACTION';

查看此答案以获取有关设置 sql_modes 的更多详细信息:https://stackoverflow.com/a/26104070/2469308

【讨论】:

  • 谢谢 Madhur Bhaiya - 第一个解决了我的问题。是的 ack_ts(Acknowledgment time) 应该总是大于显示时间。
猜你喜欢
  • 2014-11-05
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
相关资源
最近更新 更多