• 创建新表,自动授权trigger


    需求

         一个用户下三个表,开发人员不定时进行rename表名称,create原表名称 as old_table 插入少量数据,另一个业务用户需要访问该表,由于表名称rename导致经常需要手工授权。

        需求转型12.1,新创建的表,自动给开发用户进行授权,由于用户很多,因此新表对角色进行授权。

    一、模拟场景

    目标表hr.t1,业务用户scott 
    SQL> create table hr.t1 as select * from hr.employees;
    SQL> grant select on hr.t1 to scott;
    SQL> conn scott/tiger
    已连接。
    SQL>
    SQL> select count(*) from hr.t1;
      COUNT(*)
    ----------
           107
    SQL> conn hr/hr
    已连接。
    SQL> alter table t1 rename to t1_20190612_bak;
    表已更改。
    SQL> create table t1 as select * from T1_20190612_BAK where rownum<=5;
    表已创建。
    SQL> conn scott/tiger
    已连接。
    SQL> select count(*) from hr.t1;
    select count(*) from hr.t1
                            *1 行出现错误:
    ORA-00942: 表或视图不存在
    
    SQL> select GRANTEE,OWNER,TABLE_NAME,GRANTOR,PRIVILEGE from dba_tab_privs where table_name='T1_20190612_BAK';
    GRANTEE    OWNER      TABLE_NAME      GRANTOR              PRIVILEGE
    ---------- ---------- --------------- -------------------- ----------
    SCOTT      HR         T1_20190612_BAK HR                   SELECT
    表名称rename后,授权对象自动更换为修改后的对象名称。 

    二、测试解决方案

    2.1 同义词

    排除权限不足,测试同义词rename后的对象是否会跟随rename修改
    SQL> grant select any table to scott;
    SQL> create table t2 as select * from T1_20190612_BAK;
    SQL>  conn scott/tiger
    SQL> create or replace synonym t2 for hr.t2;
    同义词已创建。
    SQL> select count(*) from t2;
      COUNT(*)
    ----------
           107
    SQL> alter table t2 rename to T2_20190612_BAK;
    SQL>  select count(*) from t2;
     select count(*) from t2
                          *1 行出现错误:
    ORA-00980: 同义词转换不再有效
    
    SQL> select OWNER,SYNONYM_NAME,TABLE_OWNER,TABLE_NAME from dba_synonyms where table_name='T2';
    OWNER      SYNONYM_NA TABLE_OWNE TABLE_NAME
    ---------- ---------- ---------- ------------------------------
    SCOTT      T2         HR         T2
    SQL>  select owner,object_name,object_type,status from dba_objects where owner='SCOTT' and object_name='T2';
    OWNER      OBJECT_NAME          OBJECT_TYPE         STATUS
    ---------- -------------------- ------------------- -------
    SCOTT      T2                   SYNONYM             VALID
    SQL>  create table t2 as select * from T2_20190612_BAK where rownum<=5;
    SQL> select count(*) from t2
      COUNT(*)
    ----------
             5

    总结,本次第一个需求,使用同义词即可。但是第二个需求,如果需要对数据库新表进行授权如何操作呢?

    2.2 创建触发器

    http://blog.itpub.net/27042095/viewspace-741198/
    http://blog.itpub.net/25016/viewspace-926488/
    
    ORA_DICT_OBJ_NAME:用于返回DDL操作所对应的数据库对象名
    ORA_DICT_OBJ_OWNER:用于返回DDL操作所对应的对象的所有者名。
    ORA_DICT_OBJ_TYPE:用于返回DDL操作所对应的数据库对象的类型。
    
    --11.2.0.4
    create or replace trigger GRANT_NEWTABLE
      after create on database
    DECLARE
      v_owner       varchar(30);
      v_table_name  varchar(30);
      v_object_type varchar(30);
      v_sql         varchar2(400);
    begin
      v_owner       := SYS.DICTIONARY_OBJ_OWNER;
      v_table_name  := SYS.DICTIONARY_OBJ_NAME;
      v_object_type := SYS.dictionary_obj_type;
      IF (v_owner in ('HR') and v_object_type='TABLE') THEN
          v_sql := 'grant select,insert,update,delete on ' || v_owner || '.' ||v_table_name || ' TO rolea';
      DBMS_SCHEDULER.create_job (
        job_name        => 'test',
        job_type          => 'PLSQL_BLOCK',
        job_action        => 'Begin profile(''' || v_sql || '''); end ;',
        start_date        => SYSTIMESTAMP,
        repeat_interval => NULL ,
        end_date         => NULL,
        enabled           => TRUE,
        comments        => 'Run DDL from the trigger');
       end if;
       end;
       /
    --12.1(由于DBMS_SCHEDULER JOB创建语法不同导致,上述11g版本输入无法执行)
    create or replace trigger GRANT_NEWTABLE
      after create on database
    DECLARE
      v_owner       varchar(30);
      v_table_name  varchar(30);
      v_object_type varchar(30);
      v_sql         varchar2(400);
    begin
      v_owner       := SYS.DICTIONARY_OBJ_OWNER;
      v_table_name  := SYS.DICTIONARY_OBJ_NAME;
      v_object_type := SYS.dictionary_obj_type;
      IF (v_owner in ('HR') and v_object_type='TABLE') THEN
          v_sql := 'grant select,insert,update,delete on ' || v_owner || '.' ||v_table_name || ' TO rolea';
      DBMS_SCHEDULER.create_job (
        job_name        => 'test',
        job_type          => 'PLSQL_BLOCK',
        job_action        => 'begin 
     execute immediate '''||v_sql||''';
     end;',
        start_date        => SYSTIMESTAMP,
        repeat_interval => NULL ,
        end_date         => NULL,
        enabled           => TRUE,
        comments        => 'Run DDL from the trigger');
       end if;
       end;
       /
  • 相关阅读:
    如何解决加载动态链接库DLL失败,返回0,GetLastError返回错误码126
    如何实现点击激活窗体同时窗体不跑到最前覆盖其他窗体
    数据库04
    数据库03
    数据库02
    数据库01
    Linux02
    Linux01
    软件质量
    HTML04
  • 原文地址:https://www.cnblogs.com/lvcha001/p/11088611.html
Copyright © 2020-2023  润新知