如何检查MySQL中的BIT数据类型?

时间:2018-05-24 05:48:58

标签: mysql sql bit

我在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 = ?

2 个答案:

答案 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.您应该首先检查您是否正在测试正确的位。