|
最近用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)
复制代码
|
|