CREATE OR REPLACE TRIGGER EAP.DROP_TRIGGER
before drop on schema
begin
raise_application_error(-20000, 'con_not_drop!');
end;

只限制schema, 不限制其他用户吧,是用schema测试的吗


如果TRIGGER的属主SCHEMA,即EAP,要DROP 任何EAP.*, 会触发该TRIGGER。如果别的SCHEMA(比如SYS和ABC用户),拥有DROP ANY TABLE 的权限,那么这些用户drop table EAP.table1时,不会触发该TRIGGER。作者的目的,无非是想禁止EAP下的OBJECT被错误地DROP掉。那只能是在TRIGGER里加如下语句,显式地列出拥有DROP权限的SCHEMA, 对其做限制:
if upper(ora_login_user) in ('SYS','ABC') then
raise_application_error(-20000, 'con_not_drop!');
end if;


先记录一下当时的ora_login_user再说:
create table tb_who_drops(schema_name varchar2(40),drop_time date);
TRIGGER改成如下:
CREATE OR REPLACE TRIGGER DROP_TRIGGER
before drop on schema
begin
insert into tb_who_drops values (ora_login_user,sysdate);
--raise_application_error(-20000, 'can_not_drop!');
end;
/
然后EAP用户DROP一个OBJECT,再查询TB_WHO_DROPS,看看是否记录了 ora_login_user


那就怪了,说明EAP用户DROP表时,根本没有触发该触发器。我的环境是12.0.1,你是11GR2,应该没啥区别吧。


CREATE OR REPLACE TRIGGER DROP_TRIGGER
before drop on EAP.SCHEMA
begin
--insert into tb_who_drops values (ora_login_user,sysdate);
raise_application_error(-20000, 'can_not_drop!');
end;
/
试试看指定EAP用户是否生效,我这边操作sys指定EAP用户,或是EAP用户直接schema都可以被触发器限制


我怀疑可能和EAP用户某些权限有关。要不这样,禁用EAP下的相关DROP_TRIGGER。然后在SYS用户下:
create table tb_who_drops(schema_name varchar2(40),drop_time date);
CREATE OR REPLACE TRIGGER DROP_TRIGGER
before drop on database
begin
insert into tb_who_drops values (ora_login_user,sysdate);
end;
/
然后EAP用户登录,去DROP一个它下面的OBJECT。之后在SYS.TB_WHO_DROPS查一下有无记录相关记录(我测试时是记录了的)。如有记录,则改SYS下的DROP_TRIGGER如下,也可以达到同样效果,任何用户都不能DROP EAP用户下的OBJECT了:
CREATE OR REPLACE TRIGGER DROP_TRIGGER
before drop on database
begin
if upper(ora_dict_obj_owner)='EAP' THEN
raise_application_error(-20000, 'can_not_drop!');
END IF;
end;
/


