|  | 
 
| 最近用CI实现公司一个MIS的过程中,碰到一个数据权限管理问题。郁闷了好一阵。 最后追踪 金蝶 k3 的权限管理 sql。找到了解决办法。现在我把我的思路贴上来供大家参考。
 
 问题描述:
 实现和ERP类似的对基础资料的查看,编辑,删除权限控制。 我用的 sql server 2005
 
 (一)先贴上 k3 数据库跟踪的代码
 
 
 SQL复制代码 复制代码 -- 查询数据
 SELECT t1.FItemID,MIN(t1.FParentIDX) AS FParentIDX
 ,(CASE WHEN MAX(SUBSTRING(t1.FdataAccessDelete,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END) AS FDeleteAccess
 ,(CASE WHEN MAX(SUBSTRING(t1.FDataAccessEdit,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END ) AS FEditAccess
 ,(CASE WHEN MAX(SUBSTRING(t1.FDataAccessView,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END) AS FViewAccess
 FROM t_user t0 INNER JOIN Access_t_ICItem t1
 ON t0.FuserID=16417 --16417用户ID
 GROUP BY t1.FItemID
 
 -- 修改数据
 UPDATE Access_t_Organization SET FDataAccessView=
 SUBSTRING(FDataAccessView,1,11)+CONVERT(BINARY(1),SUBSTRING(FDataAccessView,12,1) & 239)+SUBSTRING(FDataAccessView,13,88)
 WHERE FParentIDX=25263 OR FItemID=25263
 
 
 (二)原理测试sql
 
 
 SQL复制代码 复制代码 --select power( 2,7-(@id+7)%8 )                                 -- power( 2,7-(@id+7)%8 ) 数据存放在字节的哪一位
 --select substring( @accesssetting,@id/8+1,1 )  -- ( @id/8+1 ) 数据存放在哪个字节
 
 DECLARE @id AS INT                                                      SET @id = 5
 -- 假设用户的 id =5
 DECLARE @accesssetting AS BINARY(200)           SET @accesssetting = CONVERT(BINARY(200),0)
 -- 假设基础资料存放权限的字段为  200 字节(支持 200 * 8 为用户)
 -- 且默认所有人都没有权限 (全 0 )
 
 -- 查询用户的权限,值为 0 没有权限
 SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
 -- 修改用户 id 的权限
 -- 通过 用户id 和 权限字段的位数计算出 用户权限存放字节的前后区间
 DECLARE @start_1 AS INT,@offset_1 AS INT,@start_2 AS INT, @offset_2 AS INT
 SELECT @start_1         = CASE WHEN ( @id/8+1 ) > 1 THEN 1 ELSE 0 END
 SELECT @offset_1        = CASE WHEN ( @id/8+1 ) > 1 THEN ( @id/8+1 ) - 1 ELSE 0 END
 SELECT @start_2         = CASE WHEN ( @id/8+1 ) < 200 THEN ( @id/8+1 ) + 1 ELSE 0 END
 SELECT @offset_2        = CASE WHEN ( @id/8+1 ) < 200 THEN 200 - ( @id/8+1 ) ELSE 0 END
 -- select @start_1,@offset_1,@start_2,@offset_2
 
 -- 授予用户权限(  |  位或操作符, power 求平方 )
 SELECT @accesssetting = SUBSTRING( @accesssetting,@start_1,@offset_1 )
 + CONVERT( BINARY(1),SUBSTRING(@accesssetting, @id/8+1 ,1) | POWER(2,7-(@id+7)%8))
 + SUBSTRING(@accesssetting,@start_2,@offset_2)
 
 -- 可以看到,值为8 有权限
 SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
 -- 取消用户权限(  ~  位非操作符 )
 SELECT @accesssetting = SUBSTRING( @accesssetting,@start_1,@offset_1 )
 + CONVERT( BINARY(1),SUBSTRING(@accesssetting, @id/8+1 ,1) & ( ~ POWER(2,7-(@id+7)%8) ) )
 + SUBSTRING(@accesssetting,@start_2,@offset_2)
 
 -- 好咯,权限已取消
 SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
 
 
 
 
 
 | 
 |