You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL BIT类型权限校验异常:触发器始终抛出无删除权限错误

问题分析与解决方案

你的触发器始终抛出错误的核心原因是MySQL运算符优先级导致的逻辑错误,另外还有几个需要注意的细节,我来一步步拆解:

1. 运算符优先级的致命问题

在你的触发器条件中:

IFNULL((@deleting_permission & b'10000000000' > 0), 0) < 1

MySQL中,比较运算符(>)的优先级高于位运算符(&),所以这个表达式会被MySQL解析成:

IFNULL((@deleting_permission & (b'10000000000' > 0)), 0) < 1

而b'10000000000'是非零值,所以b'10000000000' > 0的结果是1(布尔值在MySQL中以1/0表示)。最终你实际上是在判断@deleting_permission & 1 > 0——也就是检查权限的最低位(第1位),而不是你想要的对应b'10000000000'的目标权限位。

哪怕是全权限的用户,只要逻辑判断的位不符合预期,这个条件就会触发错误。

2. 修正触发器代码

你需要把位运算的部分用括号括起来,确保先执行位与操作,再判断结果是否大于0:

SELECT permissions INTO @deleting_permission FROM users WHERE id = new.deleter_id;
IF old.deleted <> new.deleted THEN
    -- 用括号明确位运算优先执行,再判断结果是否大于0
    IF (IFNULL(((@deleting_permission & b'10000000000') > 0), 0) < 1) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You cannot delete post";
    END IF;
END IF;

3. 额外需要检查的细节

  • 位掩码的位数是否匹配:你的permissions是bit(15),b'10000000000'是11位二进制数,对应十进制的1024(2^10)。请确认这个掩码确实对应你想要控制的删除权限位,避免位位置搞反(比如把从左数的位当成了从右数的位)。
  • 全权限赋值的验证:你用UPDATE users SET permissions = -1 WHERE id = ?设置全权限是正确的——bit(15)类型存储-1时会转成15个1的补码(全权限)。可以用以下语句验证实际存储的二进制值:
    SELECT id, BIN(permissions) FROM users WHERE id = 2;
    
  • new.deleter_id是否正确赋值:确保执行更新操作时,new.deleter_id确实被设置为目标用户的ID(比如2),如果这个字段为NULL,@deleting_permission会是NULL,IFNULL后返回0,也会触发错误。

内容的提问来源于stack exchange,提问作者Martin AJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:44