sql两个表,一个角色表一个是用户表,一个用户可拥有多个角色,如何统计每个用户所有角色权限值按位求和

角色表:ID,LIMITPARTNAME(角色名),LIMITPARTVALUE(权限值)
用户表:ID,USERID(用户ID),LIMITPARTID(角色表ID)
LIMITPARTVALUE(权限值)为32位整形,每一位表示一权限,查询指定用户表的USERID所有角色相应的权限值按位求和?

其实主要就是权限合并,这个算是位运算中的或运算(or),在MSSQL中可以使用|运算符来实现如 x|y,Oracle没有直接或运算符,但是提供了bitand与运算函数 可以通过 x+y-bitand(x,y)来实现

而现在LZ要求是要带聚合函数性质的或运算,这个有MSSQL和Oracle都有不同的实现方法

【MSSQL】

可以创建一个函数fn_getuserpurview,参数@userid是数值型,用来传用户ID,返回值32位整型 作用就是计算此用户的最终权限

关键语句如下

select @ret=isnull(@ret,0)|isnull(LIMITPARTVALUE,0) from 角色表,用户表 where 角色表.ID=用户表.LIMITPARTID and 用户表.UserID=@userid

其他语句LZ可以自行补充

实际调用时可以select UserID as 用户ID,dbo.fn_getuserpurview(UserID) as 权限 from 用户表 group by UserID

【Oracle】

方法一:和MSSQL思路一样,创建函数计算用户最终权限,因为oracle没有select赋值,可以使用for in 的游标赋值

关键语句如下

for cur in (select  nvl(LIMITPARTVALUE,0) as FP from 角色表,用户表 where 角色表.ID=用户表.LIMITPARTID and 用户表.UserID=p_userid) loop
  o_ret := nvl(o_ret,0)+cur.FP-bitand(nvl(o_ret,0),cur.FP);
end loop;

其他语句自行补充

方法二:使用自定义聚合函数,创建自定义聚合函数fn_bitor

--1.新建type ob_bitcat
--drop type ob_bitcat;
-- 定义类型 聚合函数的实质就是一个对象   
create or replace type ob_bitcat as object (   
    m_cat number,   
    --对象初始化  
    static function ODCIAggregateInitialize(v_self In Out ob_bitcat)   
        return number,   
        --聚合函数的迭代方法(这是最重要的方法)   
    member function ODCIAggregateIterate(self In Out ob_bitcat,value in number)   
        return number,   
        --当查询语句并行运行时,才会使用该方法,可将多个并行运行的查询结果聚合   
    member function ODCIAggregateMerge(self In Out ob_bitcat,v_next In Out ob_bitcat)   
        return number,   
        --终止聚集函数的处理,返回聚集函数处理的结果   
    member function ODCIAggregateTerminate(self In Out ob_bitcat,o_returnValue Out number,i_flags in number)   
        return number   
);
--2.建立type body strcat_type 
create or replace type body ob_bitcat is  
  static function ODCIAggregateInitialize(v_self IN OUT ob_bitcat) return number   
  is  
  begin  
      v_self := ob_bitcat(null);   
      return ODCIConst.Success;   
  end;   
  member function ODCIAggregateIterate(self In Out ob_bitcat,value in number)      
  return number   
  is  
  begin   
      self.m_cat := nvl(self.m_cat,0)+nvl(value,0)-bitand(nvl(self.m_cat,0),nvl(value,0));   
      return ODCIConst.Success;   
  end; 
  member function ODCIAggregateMerge(self In Out ob_bitcat,v_next In Out ob_bitcat)   
  return number   
  is  
  begin  
      self.m_cat := nvl(self.m_cat,0)*nvl(v_next.m_cat,0)+bitand(nvl(self.m_cat,0),nvl(v_next.m_cat,0));   
      return ODCIConst.Success;   
  end;   
  member function ODCIAggregateTerminate(self In Out ob_bitcat,o_returnValue Out number,i_flags in number)   
  return number   
  is  
  begin 
      o_returnValue := self.m_cat;   
      return ODCIConst.Success;   
  end;    
end;
--3.建立函数fn_bitor
CREATE OR REPLACE FUNCTION fn_bitor(value number)   
RETURN number -- 返回值   
PARALLEL_ENABLE AGGREGATE USING ob_bitcat; --使平行累加


最后使用下面语句得出最后结果

select UserID,fn_bitor(LIMITPARTVALUE) from 角色表,用户表 where 角色表.ID=用户表.LIMITPARTID group by UserID

追问

就是这个意思,就是那个函数,在MYSQL中如何建呢?

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-08-06
select LIMITPARTVALUE
from 用户表,角色表 where 用户表.limitpartid=角色表.ID
and UserId=@Userid
第2个回答  2013-08-04
查询如下

select LIMITPARTVALUE
from 用户表,角色表 where 用户表.limitpartid=角色表.ID
and UserId=@Userid

按位求和,不知道你想要做什么?追问

LIMITPARTVALUE为角色相应的权限值,一个用户可以有多个角色,他的总权限就是各角色相应权限值按位和

相似回答