zoukankan      html  css  js  c++  java
  • 万能组织设计及实现

    万能组织设计及实现

    作者:童振华




    说明

    1)        系统ID:用于标记归属哪个系统,以适应多系统。比如角色,权限,考虑到不同系统,在组织机构的划分上有不同的分法也加上。

    2)        用户与部门的关系:一般要求一个用户只属于一个部门。比如一个人即是领导,又是书记,那么这种关系应该由职务表来体现。如果有一个用户即属于A部门,又属于B部门,那么可以再加一个ID做为主键。登录时让用户选择登录部门。

    3)        权限:主要基于角色,考虑到灵活性同时提供特权表。最后用户的权限由用户权限视图来体现。

    Select 用户ID,权限ID from  用户角色表 PR,角色权限表 RR

       where PR.角色ID=RR.角色ID

    UNION

    Select 用户ID,权限ID from 用户权限表

    4)        用户具体信息:由用户信息表来实现。

    基于Oracle的实现
    ORACLE是一个优秀的关系型数据库,它的数据可以直接呈现出树型结构的联系。

    1. 树结构的描述

    树结构的数据存放在表中,数据之间的层次关系即父子关系,通过表中的列与列间的关系来描述,如部门表中的ID和父ID。ID表示该部门的编号,父ID表示该部门的上级部门编号。在表的每一行中都有一个表示父节点的MGR(除根节点外),通过每个节点的父节点,就可以确定整个树结构。

    在SELECT命令中使用CONNECT BY 和START WITH 子句可以查询表中的树型结构关系。其命令格式如下:

    SELECT 。。。

    CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 裂名2}

    [START WITH];

    其中:CONNECT BY子句说明每行数据将是按层次顺序检索,并规定将表中的数据连入树型结构的关系中。PRIORY运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR运算符在一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。在连接关系中,除了可以使用列名外,还允许使用列表达式。START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。

    例子1:组织树

    SQL>  select DEPT_ID,DEPT_NAME,PARENTID from dept

         CONNECT BY PARENTID=PRIOR  DEPT_ID start with dept_id=1;

     

       DEPT_ID DEPT_NAME                                            PARENTID

    ---------- -------------------------------------------------- ----------

             1 执法系统                                                    0

             2 市局                                                        1

            30 市局待分配                                                  2

             3 上城区局                                                    1

            20 上城待分配                                                  3

             4 下城区局                                                    1

            21 下城待分配                                                  4

             5 江干区局                                                    1

            22 江干待分配                                                  5

             6 拱墅区局                                                    1

            23 拱墅待分配                                                  6

     

    例子2:查找上级组织

    SQL>  select DEPT_ID,DEPT_NAME,PARENTID from dept

         CONNECT BY PRIOR PARENTID=  DEPT_ID start with dept_id=20;

     

       DEPT_ID DEPT_NAME                                            PARENTID

    ---------- -------------------------------------------------- ----------

            20 上城待分配                                                  3

             3 上城区局                                                    1

             1 执法系统                                                    0

    注意:请注意例子1与例子2中PRIOR的位置

     

    例子3:选取一个结点,列出本组织下的所有用户

    select * from (--去因为左连接造成的空记录

    select * from  (--建树

    select d.dept_id,--建组织表

            d.dept_name,

            d.parentid,

            p.person_id,

            p.person_name

       from dept d,

            person_dept pd,

            person p

      where pd.dept_id(+) = d.dept_id and p.person_id(+)=pd.person_id )--建组织表

       CONNECT BY PRIOR  dept_id=parentid

        START WITH dept_id=20 -- 这里输入结点ID

    ) where person_id<>0

     

    结果:

    DEPT_ID,DEPT_NAME,PARENTID,PERSON_ID,PERSON_NAME

    20,上城待分配,3,10968,李XX

    20,上城待分配,3,10266,高XX

    20,上城待分配,3,10268,李AB

    20,上城待分配,3,10269,童XX

    20,上城待分配,3,10410,祝XX

    20,上城待分配,3,10413,陈XX

    20,上城待分配,3,10416,任X

    20,上城待分配,3,10420,金XX

    下面解释一下上述的SQL

    其中

    select d.dept_id,--建组织表

            d.dept_name,

            d.parentid,

            p.person_id,

            p.person_name

       from dept d,

            person_dept pd,

            person p

      where pd.dept_id(+) = d.dept_id and p.person_id(+)=pd.person_id )--建组织树

    然后外面加上

    select * from  (--建树  和CONNECT BY PRIOR  dept_id=parentid

        START WITH dept_id=20 -- 这里输入结点ID

    进行截支,

    然后再套一层select消去因为左连接造成的空记录

    如果觉得上述的SQL难以理解的话,我们也可通过视图来分步实现

    create or replace view TT as

    select dept.dept_id,

            dept.dept_name,

            dept.parentid,

            person_dept.person_id

       from dept,

            person_dept

      where person_dept.dept_id = dept.dept_id;

     

    SELECT * FROM TT

    CONNECT BY PRIOR  dept_id=   parentid

          START WITH dept_id= 2;

     

    例子4:使用level改变结果的显示方式

    SELECT dept.dept_id,RPAD(' ',(LEVEL-1)*3) ||dept.dept_name,dept.parentid,dept.sts  FROM dept where sts='A'

         CONNECT BY  PRIOR dept_id=  parentid

          START WITH dept_id= 1

     

    DEPT_ID,RPAD('',(LEVEL-1)*3)||DEPT.DEP,PARENTID,STS

    2,   市局,1,A

    30,      市局待分配,2,A

    3,   上城区局,1,A

    20,      上城待分配,3,A

    52,         上城一中队,20,A

    4,   下城区局,1,A

    21,      下城待分配,4,A

    5,   江干区局,1,A

    22,      江干待分配,5,A

  • 相关阅读:
    TOYS POJ
    口罩发放
    Qin Shi Huang's National Road System HDU
    次小生成树
    ACM Contest and Blackout UVA
    Strongly connected HDU
    tarjan
    Network HDU
    【洛谷 1351】联合权值
    【洛谷 3884】二叉树问题
  • 原文地址:https://www.cnblogs.com/tongzhenhua/p/127601.html
Copyright © 2011-2022 走看看