【问题标题】:Best process strategy for maintaining table access when dropping and re-creating tables删除和重新创建表时维护表访问的最佳流程策略
【发布时间】:2015-12-18 16:34:13
【问题描述】:

是否可以在 Oracle 12c 数据库中为所有权限编写权限脚本,但同时又不具有修改架构中的对象或数据的权限?

我需要能够在删除和重新创建表之前对表的现有权限编写脚本,以便在重新创建表后重新应用权限。我必须将脚本提交给 DBA 才能运行,并且在删除和重新创建表时需要包含这些权限。如果我看不到现有权限,则无法包含它们。 DBA 不允许我自己拥有这样做的权利

但他只会运行我 100% 自己编写的脚本。

当我在使用与架构名称不匹配的 ID 登录时尝试查看表的 DDL 时,我收到以下错误:

要提取审计选项,您必须对 DBA_OBJ_AUDIT_OPTS 或登录到您正在提取的架构。

授予对 DBA_OBJ_AUDIT_OPTS 的 SELECT 权限是否可以让我查看对表进行的所有授予,而无需提供额外的权限来修改架构或数据?

【问题讨论】:

    标签: oracle security oracle12c


    【解决方案1】:

    不要使用DROP TABLE/CREATE TABLE。请改用DBMS_REDEFINITION。这是我为此功能保留的示例代码的修改版本:

    CREATE TABLE my_preexisting_table 
      ( a number,
        constraint my_preexisting_table_pk primary key (a) );
    
    GRANT SELECT, UPDATE ON my_preexisting_table TO ont;
    
    -- Start the online redefinition process...
    
    -- First, check whether your table is a candidate for the process
    BEGIN
    DBMS_REDEFINITION.CAN_REDEF_TABLE('apps','my_preexisting_table',
          DBMS_REDEFINITION.CONS_USE_ROWID);
    END;
    /
    
    -- Create your new table with a new name.  This will eventually replace the pre-existing one
    --DROP TABLE apps.my_preexisting_table_redef;
    
    CREATE TABLE apps.my_preexisting_table_redef
    (
      new_column1     NUMBER,
      a               NUMBER,
      new_column2     DATE,
      -- Let's change the primary key while we're at it
      -- Unfortunately, we have to rename our constraints because they share a global namespace 
      constraint my_preexisting_table_pk_r primary key (new_column1, a)  
    )
    -- Let's partition the table while we're at it...
    PARTITION BY RANGE (new_column2)
    INTERVAL (NUMTODSINTERVAL (1,'DAY')) ( partition my_preexisting_table_old values less than (to_date('01-JAN-2000','DD-MON-YYYY') ));
    ;
    
    
    -- Takes long if your table is big.
    BEGIN
    DBMS_REDEFINITION.START_REDEF_TABLE('apps', 'my_preexisting_table','my_preexisting_table_redef',
    -- Map columns from the existing table to the new table here
           'a new_column1, a a, sysdate new_column2',
            dbms_redefinition.cons_use_rowid);
    END;
    /
    
    DECLARE
    num_errors PLS_INTEGER;
    BEGIN
    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('apps', 'my_preexisting_table','my_preexisting_table_redef',
       DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
    
      DBMS_OUTPUT.PUT_LINE('Copy depenedent objects: num_errors = ' || num_errors);   
    END;
    
    
    -- Make sure there were no problems... or, if there were problems then they were expected.  For example,
    -- there will be an error listed because it cannot copy the PK constraint from the original table (because we made a new one already)
    -- and that's OK.
    select * from         DBA_REDEFINITION_ERRORS where base_table_name = 'MY_PREEXISTING_TABLE';
    
    
    BEGIN
    DBMS_REDEFINITION.FINISH_REDEF_TABLE('apps', 'my_preexisting_table', 'my_preexisting_table_redef');
    END;
    /
    
    
    -- Check out the results.
    select * from my_preexisting_table;
    
    -- Verify the grants are still in place...
    select * from DBA_TAB_PRIVS where table_Name = 'MY_PREEXISTING_TABLE';
    
    -- Drop our redef table when ready...
    DROP TABLE apps.my_preexisting_table_redef;
    

    【讨论】:

    • 您是否有理由不遵循 Oracle 文档中给出的过程? Redefining Tables Online
    • 不,没有理由。我给出的答案是有效的,但如果我以可能导致实际问题的方式偏离最佳实践,我将感谢您的 cmets。
    • 顺便说一句...您提供的链接非常肯定我在回答中所做的。此外,我不将其视为最佳实践的处方,而更多的是该过程的端到端示例。你有什么特别反对的吗?
    • 好吧,我对评论“Redefine your table online”感到困惑,然后是DBMS_REDEFINITION.CAN_REDEF_TABLE。实际上,您遵循文档中的流程。
    • 谢谢。我做了一些小的修改,希望更清晰。
    【解决方案2】:

    在应用程序架构上创建一个函数,该函数返回对该架构拥有的表的对象权限,然后授予自己执行该函数的权限。

    这是解决问题的最简单方法。纵观全局,有更好的方法,但这些方法可能需要对流程进行重大更改。

    • 使用 ALTER 而不是 DROP 和 CREATE。有很多很多依赖对象类型,不可能全部考虑。例如,这些表是否有任何 虚拟专用数据库谓词、基于列使用情况构建的直方图等。在代码“存在”在数据库中的环境中,DROP 是敌人。
    • 将数据库的“一个真实版本”存储在版本控制的文本文件中。这是您可以安全地删除表并确切知道如何重建它们的唯一方法。 只有在本地数据库上删除和重新创建模式数百次后,您的组织才能真正了解事情的运作方式。

    这是最简单的方法:

    示例架构

    drop table test1;
    create table test1(a number);
    grant select on test1 to system;
    grant references on test1 to system with grant option;
    

    创建函数以生成脚本

    在应用程序架构上创建此函数。

    create or replace function get_table_grants(p_table_name in varchar2) return clob is
    --Purpose: Return the object grants for a table.
        v_ddl clob;
    begin
        --Enable the SQL terminator, ";" or "/".
        dbms_metadata.set_transform_param(
            dbms_metadata.session_transform,
            'SQLTERMINATOR',
            true);
    
        --Get the DDL.
        select dbms_metadata.get_dependent_ddl(
            object_type => 'OBJECT_GRANT',
            base_object_name => upper(trim(p_table_name)),
            base_object_schema => user)
        into v_ddl
        from dual; 
    
        --Return the DDL.
        return v_ddl;
    end get_table_grants;
    /
    
    --Grant access to yourself.
    grant execute on get_table_grants to YOUR_USERNAME;
    

    样本输出

    select get_table_grants('TEST1') from dual;
    
      GRANT REFERENCES ON "JHELLER"."TEST1" TO "SYSTEM" WITH GRANT OPTION;
      GRANT SELECT ON "JHELLER"."TEST1" TO "SYSTEM";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2011-05-26
      • 2020-12-18
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多