如何在mysql中检查位数据类型?

daupos2t  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(451)

我有一个专栏 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;

它总是抛出:
您不能删除帖子
即使对于#2用户 111111111111111 权限值。怎么了?
注意到我更新了 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 = ?
xv8emn3q

xv8emn3q1#

如果你想和 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。

i5desfxk

i5desfxk2#

选择字段 active 在触发器中检查权限,但根据您的问题,权限是在 permissions 现场。
更改查询以使用后一个字段:

SELECT `permissions` INTO @active_deleter FROM users WHERE id = new.deleter_id;

还有,你的 permissions 字段有15位。你用的面具只有10个。你应该首先检查你是否测试了正确的位。

相关问题