更新整数列中的特定位

28
我有一个MySQL表,其中用户权限以位掩码形式存储:
|user   | permissions |
| Admin | 31          |
| User  | 13          |

           16 8  4  2  1
Admin ->   1  1  1  1  1  -> 16 + 8 + 4 + 2 + 1 -> 31
User  ->   0  1  1  0  1  ->  8 + 4 + 1 -> 13

现在我想使用SQL查询为每个用户添加一个权限。 假设我想为所有人添加权限16,而不修改其他位。

 UPDATE users SET permission = ????

我该如何做到这一点?


请尝试此链接:http://stackoverflow.com/questions/6498881/how-to-bitwise-or-into-a-binary100 - AnandPhadke
那么,你能展示一下你的更新后的数据吗? - AnandPhadke
1
User -> 1 1 1 0 1 -> 29 - Jürgen Steinblock
@AnandPhadke - 那个链接是用于存储许多字节的数据类型;这需要比这个问题更复杂的解决方案。 - ToolmakerSteve
2个回答

59

要添加权限16,只需执行以下操作:

UPDATE users SET permission = permission | 16;

按位或运算符会打开位。要关闭它们,请使用与要关闭的位的补码进行AND操作:

UPDATE users SET permission = permission & ~16

为了泛化到多个位:假设您想要同时设置值为16和2的位。这是二进制值 b'10010'。所以第一个片段将以以下方式结束:= permission | b'10010'; 相应的清除将以以下方式结束:= permission & ~b'10010'; - ToolmakerSteve
如果您更喜欢编写位的十进制值,则可以通过以下方式设置多个位:设置多个位: ... = permission | (16+2);清除多个位: ... = permission & ~(16+2); - ToolmakerSteve

4
你应该研究一下 MySQL的SET。它可能会让你的生活更轻松。不用使用这种奇怪的二进制逻辑,你可以创建一个集合并让MySQL为你执行二进制逻辑。这将限制可能的程序员错误、调试问题,并使你的代码更易读。
但如果你一心想使用整数,请查看位函数。例如,要查看权限16是否已设置:
SELECT permission<<4 & 1 FROM users

如果您想添加权限:

UPDATE users SET permission = permission | 16

第一个代码片段是错误的。应该是permission>>4,向下移位到个位数。另一种替代移位的方法是直接使用二进制字面量。SELECT permission & b'10000' ...测试值为16的位。或者使用SELECT permission & 16 ... - ToolmakerSteve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接