如何针对负值安全地更新未签名记录?

Posted

技术标签:

【中文标题】如何针对负值安全地更新未签名记录?【英文标题】:How to update an unsigned record safely against negative value? 【发布时间】:2021-12-31 19:34:34 【问题描述】:

我有一个这样的触发器,它将总值保留在父表中:

UPDATE posts p SET total_comments = GREATEST(total_comments - 1, 0) WHERE old.post_id = p.id

我使用GREATEST() 来避免负数,但如果total_comments 的当前值为0 然后触发器执行,我仍然会收到此错误:

#1690 - BIGINT UNSIGNED 值超出 (mydb.p.total_cmets - 1) 的范围

有什么办法吗?

【问题讨论】:

【参考方案1】:

如果它已经是0,那么如何使用where 子句来避免更新它。试试这个:

UPDATE posts p
SET total_comments = total_comments - 1
WHERE old.post_id = p.id
  AND total_comments > 0

【讨论】:

【参考方案2】:

来自Out-of-Range and Overflow Handling:

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

在您的情况下,total_comments 定义为 UNSIGNED,如果其值为 0,则表达式 total_comments - 1 的计算会引发错误。

一种解决方法是将total_commentsGREATEST() 中的1 进行比较,然后进行减法:

UPDATE posts p 
SET total_comments = GREATEST(total_comments, 1) - 1 
WHERE old.post_id = p.id

【讨论】:

以上是关于如何针对负值安全地更新未签名记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地配置 CI 服务器以对二进制文件进行数字签名?

该安装包未包含任何证书啥鬼

如何针对这组安全要求配置 WCF 客户端

MACOS安全更新|第1部分:XPROTECT的更新

如何从 Azure 数据工厂安全地调用 Azure 逻辑应用

如何安全地删除未保存的托管对象?