2015-12-18 46 views
2

在沒有同時修改模式中的對象或數據的權限的情況下,是否有權限對Oracle 12c數據庫中的所有權限進行腳本編寫?在刪除和重新創建表時維護表訪問的最佳流程策略

我需要能夠在表被刪除和重新創建之前腳本對錶上的現有權限,以便重新創建表後重新應用權限。我將不得不將腳本提交給DBA運行,並且在刪除和重新創建表時需要包含這些權限。如果我看不到現有的權限,我不能包含它們。 DBA不會允許我有權自己做這件事

但他只會運行我自己寫100%的腳本。

當我嘗試查看DDL的表,而在使用不匹配的架構名稱的ID登錄,我收到以下錯誤:

To extract audit options, you must either have SELECT privilege on DBA_OBJ_AUDIT_OPTS or log into the schema that you are extracting.

將授予對DBA_OBJ_AUDIT_OPTS SELECT權限給我能否查看桌上所有贈款,同時又不提供額外的修改架構或數據的權利?

回答

0

不要做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; 
+0

是否有一個理由,爲什麼你不按照程序如Oracle文檔中給出? [在線重新定義表格](http://docs.oracle.com/cd/B19306_01/server.102/b14231/tables.htm#ADMIN01514) –

+0

不,沒有理由。我給出的答案是作品,但是如果我偏離最佳做法的方式可能導致實際問題,我將非常感謝您的意見。 –

+0

順便說一句...你給的鏈接是非常必要的,我在我的答案中做了什麼。另外,我並不認爲它是最佳實踐的處方,而更多是端到端的流程示例。你有什麼特別反對嗎? –

0

創建基於返回由該模式擁有的表對象權限的應用模式的功能,然後授予自己來執行該功能的權限。

這是最簡單的問題解決方案。縱觀全局,有更好的方法,但這些可能需要對流程進行重大改變。

  • 用戶ALTER而不是DROP和CREATE。有很多依賴對象類型的lot,不可能全部考慮它們。例如,表中是否有任何虛擬專用數據庫謂詞 ,基於列使用情況構建的直方圖等。在代碼「存活」在數據庫中的環境中,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"; 
相關問題