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
大概就是这一个样子,已亲测可以使用。如有需要改进的地方请留言,谢谢!
posted @ 2019-03-29 15:45  小年青。  阅读(1322)  评论(0编辑  收藏  举报