zoukankan      html  css  js  c++  java
  • Oracle动态授权用户权限

    目的:由于公司数据库权限管理的很严,每次新建表后需要手动授权给相应的用户,并且还要创建同义词。这就很是麻烦。账号一多就特别花时间。所以自己写了两个存储过程和定时JOB来实现动态授权。

    需求:A用户访问B用户,A用户可以增删改查B用户所有表(不包括系统表)。A是普通用户,B用户拥有DBA权限,所以我们不能用以下方式授权,这样会把系统表的权限也放出去。

    grant select any table to a;
    grant
    all on b.table_name to a;

    一、授予A用户访问B用户现有表访问权限

    1.新建一个普通用户A。

    create user 用户名 identified by "密码" default tablespace 表空间 temporary tablespace temp;

    授予A用户resource/connect权限、创建私有同义词权限。

    grant create synonym to A;
    grant
    resource,connect to A;

    2.授予A用户访问B用户所有表权限,另存为.sql后缀,放在Command里面执行。

    select 'GRANT select, insert, update, delete ON B.'|| 表名||' to A;'  from user_tables;

    创建所有表的私有同义词,在A用户上创建

    select 'create synonym '||同义词名称||' for B.'||表名||';'  from user_tables where tablespace_name='表空间';

    以上操作是针对B用户下现有表授予A用户访问权限。

    二、通过JOB定时调用存储过程实现动态授权A用户。

    准备:A用户下两张表、两个sequence、两个触发器(可有可无)、一个存储过程、一个定时JOB。B用户一个存储过程、一个定时JOB

    两张表可根据自身需求增加相应的字段。

    1.A用户

    A用户表1

    create table CREATE_LOG
    (
      pid     INTEGER not null,
      pobject VARCHAR2(400),
      sjc     VARCHAR2(14)
    );
    alter table CREATE_LOG add primary key (PID);

    A用户表2

    create table CREATE_OBJECT
    (
      pid     INTEGER not null,
      sobject VARCHAR2(400),
      sjc     VARCHAR2(14)
    );
    alter table NEWINGS_OBJECT
      add primary key (PID);
    grant select, insert on CREATE_OBJECT to B; #授权给B用户访问,存储过程里面要用到

    sequence是给两张表主键使用的,创建一下就好了。触发器主要是实现主键自增和将空的时间戳赋值。很简单

    存储过程

    create or replace procedure create_actions is
      --scount number(10);
      snum number(10);
    begin
      declare
      cursor cur is select sobject from newings_object where sjc>=to_char(sysdate,'yyyymmdd');
      begin
      for cur_result in cur  loop
        select count(1) into snum from create_log where pobject=cur_result.sobject;
        if snum=0 then
          EXECUTE IMMEDIATE 'create synonym '||cur_result.sobject||' for B.'||cur_result.sobject;
          insert into create_log(pobject) values(cur_result.sobject);
          commit;
          end if;
          end loop;
          end;
          
      end;

    定时JOB(A、B用户定时JOB执行时间最好是错开)

    declare
      job number;
    BEGIN
      DBMS_JOB.SUBMIT(  
            JOB => job,  /*自动生成JOB_ID*/  
            WHAT => 'create_actions;',  /*需要执行的存储过程名称或SQL语句*/  
            NEXT_DATE => sysdate+3/(24*60),  /*初次执行时间-下一个3分钟*/  
            INTERVAL => 'trunc(sysdate,''mi'')+1/(24*60)' /*每隔1分钟执行一次*/
          );  
      commit;
    end;

    2.B用户

    存储过程

    create or replace procedure create_action
    is
      scount number(10);
      snum number(10);
    begin
      select count(1) into scount from user_objects where to_char(created,'yyyymmddhh24miss')>=to_char(sysdate,'yyyymmdd') and object_type='TABLE';
      declare
      cursor cur is
      select object_name from user_objects where to_char(created,'yyyymmddhh24miss')>=to_char(sysdate,'yyyymmdd') and object_type='TABLE'; 
      begin
        for cur_result in cur  loop  
        if scount>0 then 
          select count(1) into snum from A.newings_object where sobject=cur_result.object_name;
          if snum=0 then
          EXECUTE IMMEDIATE 'grant select,insert,update,delete on B.'||cur_result.object_name||' to A';
          --EXECUTE IMMEDIATE 'insert into A.newings_object(sobject) values('||cur_result.object_name||')';
          insert into roobbin.newings_object(sobject) values(cur_result.object_name);
          commit;
          end if;
          end if;
          end loop;
          end;
    end;

    定时JOB,A、B用户定时JOB执行时间最好是错开

    declare
      job number;
    BEGIN
      DBMS_JOB.SUBMIT(  
            JOB => job,  /*自动生成JOB_ID*/  
            WHAT => 'create_action;',  /*需要执行的存储过程名称或SQL语句*/  
            NEXT_DATE => sysdate+3/(24*60),  /*初次执行时间-下一个3分钟*/  
            INTERVAL => 'trunc(sysdate,''mi'')+1/(24*60)' /*每隔1分钟执行一次*/
          );  
      commit;
    end;

    附:user_jobs主要字段说明

    列名             数据类型           解释
    JOB             NUMBER             任务的唯一标示号
    LOG_USER        VARCHAR2(30)      提交任务的用户
    PRIV_USER       VARCHAR2(30)       赋予任务权限的用户
    SCHEMA_USER     VARCHAR2(30)       对任务作语法分析的用户模式
    LAST_DATE       DATE               最后一次成功运行任务的时间
    LAST_SEC        VARCHAR2(8)        如HH24:MM:SS格式的last_date日期的小时,分钟和秒
    THIS_DATE       DATE               正在运行任务的开始时间,如果没有运行任务则为null
    THIS_SEC        VARCHAR2(8)        如HH24:MM:SS格式的this_date日期的小时,分钟和秒
    NEXT_DATE       DATE               下一次定时运行任务的时间
    NEXT_SEC        VARCHAR2(8)        如HH24:MM:SS格式的next_date日期的小时,分钟和秒
    TOTAL_TIME      NUMBER             该任务运行所需要的总时间,单位为秒
    BROKEN          VARCHAR2(1)        标志参数,Y标示任务中断,以后不会运行
    INTERVAL        VARCHAR2(200)      用于计算下一运行时间的表达式
    FAILURES        NUMBER             任务运行连续没有成功的次数
    WHAT            VARCHAR2(2000)     执行任务的PL/SQL块
    INTERVAL常用参数示例
        每天午夜12点            ''TRUNC(SYSDATE + 1)''     
        每天早上8点30分         ''TRUNC(SYSDATE + 1) +8*60+30/(24*60)''     
        每星期二中午12点         ''NEXT_DAY(TRUNC(SYSDATE ), ''''TUESDAY'''' ) + 12/24''     
        每个月第一天的午夜12点    ''TRUNC(LAST_DAY(SYSDATE ) + 1)''     
        每个季度最后一天的晚上11点 ''TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), ''Q'' ) -1/24''     
        每星期六和日早上6点10分    ''TRUNC(LEAST(NEXT_DAY(SYSDATE, ''''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) +6×60+10/24×60''    
        每3秒钟执行一次             'sysdate+3/(24*60*60)'   
        每2分钟执行一次           'sysdate+2/(24*60)'   
        
        1:每分钟执行  
        Interval => TRUNC(sysdate,'mi') + 1/ (24*60) --每分钟执行  
        interval => 'sysdate+1/(24*60)'  --每分钟执行  
        interval => 'sysdate+1'    --每天  
        interval => 'sysdate+1/24'   --每小时  
        interval => 'sysdate+2/24*60' --每2分钟  
        interval => 'sysdate+30/24*60*60'  --每30秒  
        2:每天定时执行  
        Interval => TRUNC(sysdate+1)  --每天凌晨0点执行  
        Interval => TRUNC(sysdate+1)+1/24  --每天凌晨1点执行  
        Interval => TRUNC(SYSDATE+1)+(8*60+30)/(24*60)  --每天早上8点30分执行  
        3:每周定时执行  
        Interval => TRUNC(next_day(sysdate,'星期一'))+1/24  --每周一凌晨1点执行  
        Interval => TRUNC(next_day(sysdate,1))+2/24  --每周一凌晨2点执行  
        4:每月定时执行  
        Interval =>TTRUNC(LAST_DAY(SYSDATE)+1)  --每月1日凌晨0点执行  
        Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24  --每月1日凌晨1点执行  
        5:每季度定时执行  
        Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q')  --每季度的第一天凌晨0点执行  
        Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q') + 1/24  --每季度的第一天凌晨1点执行  
        Interval => TRUNC(ADD_MONTHS(SYSDATE+ 2/24,3),'q')-1/24  --每季度的最后一天的晚上11点执行  
        6:每半年定时执行  
        Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24  --每年7月1日和1月1日凌晨1点  
        7:每年定时执行  
        Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24  --每年1月1日凌晨1点执行  
    参考博客:https://www.cnblogs.com/Chestnuts/p/7068456.html
    大概就是这一个样子,已亲测可以使用。如有需要改进的地方请留言,谢谢!
  • 相关阅读:
    4-结对开发地铁
    第五周学习进度博客
    mybatis的使用
    从写json作业谈起
    工作中慢慢明白的道理
    从参与公司开发到离职
    这也是风云变幻的年代
    学习的习惯和方法跟得上时代要求
    公司中springcloud项目遇到的问题
    实习生在公司的成长
  • 原文地址:https://www.cnblogs.com/Roobbin/p/10621743.html
Copyright © 2011-2022 走看看