限制Oracle中特定模式下的DROP和ALTER表

时间:2018-06-07 20:07:21

标签: oracle

我创建了一个用户(比如DROP_PARTITION_USER)来删除表的分区。该表由不同的用户拥有(例如NORMAL_USER)。 目前,我已将 DROP ANY TABLE ALTER ANY TABLE 权限授予DROP_PARTITION_USER。当DROP_PARTITION_USER执行以下语句时,它会成功执行。

ALTER TABLE SCHEMANAME.TABLENAME DROP PARTITION <PARTITION_NAME> UPDATE GLOBAL INDEXES;

但是, DROP ANY TABLE ALTER ANY TABLE 允许DROP_PARTITION_USER删除和更改任何模式[https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9013.htm]下的任何表。 Oracle中是否有任何方法可以限制特定模式下的drop和alter table?

2 个答案:

答案 0 :(得分:2)

解决此问题的常用方法是创建一个由NORMAL_USER拥有的过程,以删除其中一个表的一个分区。

然后,您将此GRANT EXECUTE此过程发送到DROP_PARTITION_USER。

您不需要额外的权限。

CREATE OR REPLACE PROCEDURE my_drop_partition (p_table_name VARCHAR2, p_partition_name VARCHAR2) 
IS
BEGIN
  EXECUTE IMMEDIATE 'ALTER TABLE '||p_table_name||' DROP PARTITION '||p_partition_name;
END my_drop_partition;
/


GRANT EXECUTE ON my_drop_partition TO drop_partition_user;

答案 1 :(得分:1)

您可以使用DDL触发器捕获此类尝试并执行您喜欢的任何操作。例如

SQL> CREATE OR REPLACE TRIGGER STOP_THAT_STUFF
  2  before create or alter or drop on database
  3  begin
  4    if ora_dict_obj_owner in ('SCOTT') and
  5       ora_sysevent in ('DROP','ALTER') and
  6       ora_dict_obj_name = 'MY_TABLE'
  7    then
  8      raise_application_error(-20000,'What the hell are you thinking!!!!');
  9    end if;
 10  end;
 11  /

Trigger created.

SQL>
SQL> conn scott/tiger
Connected.

SQL> create table scott.my_table(x int );

Table created.

SQL> create table scott.my_other_table(x int);

Table created.

SQL> drop table my_other_table;

Table dropped.

SQL> drop table my_table;
drop table my_table
*
ERROR at line 1:
ORA-04088: error during execution of trigger 'SYS.STOP_THAT_STUFF'
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: What the hell are you thinking!!!!
ORA-06512: at line 6


SQL> desc my_table
 Name                                                                    Null?    Type
 ----------------------------------------------------------------------- -------- ----------------
 X                                                                                NUMBER(38)