在数据库查询中,常常会有这样的需求:mysql
能不能用一个字符串来动态指定一个列,而后在where子句中进行查询。sql
若是能有一个function,好比叫getColumn(string),那么,写一个查询能够是:数据库
select * from table where getColumn(string) = xxxxx;.net
可是,查遍了mysql的相关文档,也没有找到这么一个相似的function。因而只能找一个Workaround------用一个存储过程。设计
举个例子:code
CREATE TABLE `user_perm` (
`id` varchar(32) NOT NULL,
`perm1` int(10) unsigned NOT NULL DEFAULT '0',
`perm2` int(10) unsigned NOT NULL DEFAULT '0',
`perm3` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)ip
表中有3个column,每一个保存一个无符号整数,用来经过位运算来判断是否符合某种条件。文档
这种设计能够用来作权限控制、preference设置等等,每一个bit用来表明一个权限或者一种设置,总之是一个开关。本例中是一个用户权限表。字符串
问题:get
经过一个script查询,来找出全部用户都有的权限(这个权限可能已经没有用了,由于全部人都有的权限)
解决方案:
DELIMITER $$
DROP PROCEDURE IF EXISTS getUnusedPermissions;
CREATE PROCEDURE getUnusedPermissions()
BEGIN
DECLARE i INT DEFAULT 0;
SELECT COUNT(id) FROM user_perm INTO @TotalUser;
WHILE i < 93 DO
SET @c_index=((i DIV 31) + 1);
SET @colName = CONCAT('perm',@c_index);
SET @perm_sql = CONCAT('SELECT COUNT(id) FROM user_perm WHERE ',@colName,' & POW(2, MOD(?, 31)) > 0 INTO @EnabledUserNum');
PREPARE stmt1 FROM @perm_sql;
SET @c_temp = i;
EXECUTE stmt1 USING @c_temp;
IF @EnabledUserNum = @TotalUser THEN
SELECT i as Permission;
END IF;
DEALLOCATE PREPARE stmt1;
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
CALL getUnusedPermissions();
DROP PROCEDURE IF EXISTS getUnusedPermissions;
注释:
31 是由于每一个无符号整数只能使用31位,三个column,因此总共93。
题外话:
很久没有更新空间了。原来的空间转到了这里 。