我在users
表中有一个名为permissions
的列。像这样:
// users
+---------+-----------------+-------------+
| id | permissions | name |
+---------+-----------------+-------------+
| int(11) | bit(15) | varchar(20) |
+---------+-----------------+-------------+
| 1 | 001100001111101 | Jack |
| 2 | 111111111111111 | Peter |
| 3 | 110000000111011 | Martin |
+---------+-----------------+-------------+
如您所见,permissions
列具有bit(15)
数据类型。该值的每个位确定一个用户能力。例如,第一位指的是voting
- 能力,第二位指的是commenting
- 能力蚂蚁等...
我还有一个触发器BEFORE UPDATE
来调查这样的权限:
SELECT permissions INTO @deleting_permission FROM users WHERE id = new.deleter_id;
IF old.deleted <> new.deleted THEN
IF (IFNULL((@deleting_permission & b'10000000000' > 0), 0) < 1) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You cannot delete post";
END IF;
END IF;
总是抛出:
您无法删除帖子
即使对于具有111111111111111
权限值的#2用户也是如此。那有什么不对?
注意我更新permissions
列,如下所示:
-- To give some specific accesses (permissions) to the user
UPDATE users SET permissions = b'111111000101011' WHERE id = ?
-- To give full access (permissions) to the user
UPDATE users SET permissions = -1 WHERE id = ?
答案 0 :(得分:1)
如果您想使用BIT
类型,则需要使用按位运算符,而不是常规运算符。例如,如果要检查用户是否将最左边的位设置为权限,则可以执行&
操作:
SELECT permissions INTO @p FROM users WHERE id = new.deleter_id;
IF old.deleted <> new.deleted THEN
IF (b'100000000000000' & @p = 0)
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You cannot delete post";
END IF;
END IF;
上面的基本思想是文字b'100000000000000'
用作掩码,可以用来检测最左边的位(并且只有那个位)是否设置为1。它被设置为1,然后&
操作不会返回0.
具有111111111111111
权限的用户拥有所有权限的原因是任何检查一下的掩码都会返回true。
答案 1 :(得分:1)
您可以在触发器中选择字段active
来检查权限,但根据您的问题,权限会保留在permissions
字段中。
更改您的查询以使用后一个字段:
SELECT `permissions` INTO @active_deleter FROM users WHERE id = new.deleter_id;
此外,您的permissions
字段有15位。您使用的掩码只有10.您应该首先检查您是否正在测试正确的位。