我有 multiple triggers
在我正在更新统计表的数据库上。此表有一个 BIGINT UNSIGNED
列,但在更新表格时,我有时会遇到错误:BIGINT UNSIGNED value out of range
.我猜想插入的值会导致小于 0 的值,但在我看来,考虑到 IF check
,这似乎是非常奇怪的行为。在我的发言中。
我使用的语句:
UPDATE TABLE SET FileSize=774982 WHERE ID=10;
导致问题的触发器定义为:
IF (OLD.FileSize <> NEW.FileSize) THEN
INSERT INTO Statistics VALUES('FileSize', 0, 0, 0)
ON DUPLICATE KEY UPDATE Value = IF((Value - OLD.FileSize) < 0, 0, Value - OLD.FileSize);
INSERT INTO Statistics VALUES('FileSize', 0, 0, NEW.FileSize)
ON DUPLICATE KEY UPDATE Value = Value + NEW.FileSize;
END IF
如您所见,我仅在 FileSize 确实发生变化时才更新统计表 (OLD.FileSize <> NEW.FileSize
)。此外,我还添加了一个检查以确保我不会使用 IF((Value - OLD.FileSize) < 0, 0, Value - OLD.FileSize)
得到低于 0 的值。 .虽然,值 get 是一个超出范围的错误,它似乎不太可能超出 BIGINT UNSIGNED
的上限。 ,考虑到以下更新语句有效的事实?错误似乎并不总是被触发......?
如您所见,触发器由两个语句组成。简单的解释是,第一条语句从统计表中删除旧文件大小,第二条语句将新文件大小添加到表中。 (这样计算差值,正确更新统计表)
所以,我不明白我怎么会得到这个错误:Database error: BIGINT UNSIGNED value is out of range in '(DB.Statistics.Value - OLD.FileSize)' (error code: 1690, State: 22003)
新旧文件大小为244662
和 774982
分别(以字节为单位)
最佳答案
当您减去 UNSIGNED
值时,结果也是 UNSIGNED
,这意味着它不能为负数。当您尝试在 IF()
条件下计算 Value - OLD.FileSize
时出现错误。
使用比较代替减法。
INSERT INTO Statistics VALUES('FileSize', 0, 0, 0)
ON DUPLICATE KEY UPDATE Value = IF(Value < OLD.FileSize, 0, Value - OLD.FileSize);
关于MySQL BIGINT UNSIGNED 值超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53881122/