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
大概就是這一個樣子,已親測可以使用。如有需要改進的地方請留言,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM