一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何在SQL里采用位运算符(Bitwise)更新权限标志位字段?

时间:2026-06-17 08:43:47 编辑:袖梨 来源:一聚教程网

位运算更新前必须确认字段为整数类型;添加权限用 |,撤销用 & ~mask,切换用 ^;不适用于权限继承等复杂关系。

位运算更新前必须确认字段类型是整数

MySQL、PostgreSQL 和 SQL Server 都支持 &|^~ 等位运算符,但前提是目标字段(比如 permissions)必须是整数类型(TINYINTSMALLINTINTBIGINT)。如果字段是 VARCHARJSON,直接用 | 会静默转成 0 或报错(如 MySQL 的 Truncated incorrect INTEGER value)。

常见错误现象:UPDATE users SET permissions = permissions | 4 WHERE id = 123; 执行后值没变——先查 DESCRIBE users; 确认 permissions 类型,再检查是否被 ORM 自动 cast 成字符串。

给用户添加「删除」权限(按位或操作)

假设「删除」对应标志位是 8(即 2^3),要开启它,用 |(按位或):它只置 1,不影响其他位。

  • UPDATE users SET permissions = permissions | 8 WHERE id = 123;
  • 如果原值是 5(二进制 101,表示「读+写」),执行后变成 131101),新增了第 4 位(从右往左数,位索引从 0 开始)
  • 重复执行不会改变结果——13 | 8 还是 13,安全幂等

撤销「编辑」权限(按位与 + 取反)

「编辑」设为 22^1),要关掉它,不能用 & 直接和 2,那会清零其他位。正确做法是:先构造掩码(把对应位变 0,其余变 1),再用 &

掩码 = ~2(在支持符号位的语言里需小心,但主流 SQL 引擎中 ~ 对无符号整数直接按位取反;MySQL 中 ~218446744073709551613,所以更稳妥写法是显式构造):

  • MySQL/PostgreSQL 推荐:UPDATE users SET permissions = permissions & ~2 WHERE id = 123;
  • SQL Server 同样支持 ~,但注意 ~INT 返回带符号负数,可用 & 0xFFFFFFFD 替代(0xFFFFFFFD 是 32 位下除第 2 位外全 1)
  • 如果误写成 permissions & 2,结果只会剩 0 或 2,其他权限全丢

切换某权限开关(异或操作)

想让「导出」权限(设为 16)翻转(开变关、关变开),用 ^(按位异或)最简洁:

  • UPDATE users SET permissions = permissions ^ 16 WHERE id = 123;
  • 原值 16 → 变 0;原值 0 → 变 16;原值 2116+4+1)→ 变 54+1
  • 注意:这不适用于需要校验前置状态的业务逻辑(比如“仅允许管理员关闭导出”),位运算本身不带条件判断

真正容易被忽略的是:位运算无法表达「权限继承」「角色叠加」这类关系,它只适合扁平布尔标志集合。一旦权限模型变复杂(比如某功能需同时满足 A 且 B),就得退回到关联表或 JSON 字段,别硬扛。

热门栏目