triger: after servererror on database

You will always find some unusual ideas from Tom, today I just found another one incidentally.
Here is the url: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:40115659055475
And below are some extracts from this article which I think valuable for me:[@more@]

You can use this trigger -- just grab whatever info you want and record it:
ops$tkyte@ORA9IR2> create table t ( msg varchar2(4000) );

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> create or replace trigger snapshot_too_old
2 after servererror on database
3 declare
4 l_sql_text ora_name_list_t;
5 l_n number;
6 begin
7 if ( is_servererror(1555) )
8 then
9 insert into t values ( 'ora_sysevent = ' || ora_sysevent );
10 insert into t values ( 'ora_login_user = ' || ora_login_user );
11 insert into t values ( 'ora_server_error = ' || ora_server_error(1) );
12
13 l_n := ora_sql_txt( l_sql_text );
14 for i in 1 .. l_n
15 loop
16 insert into t values ( 'l_sql_text(' || i || ') = ' || l_sql_text(i) );
17 end loop;
18 end if;
19 end;
20 /

Trigger created.

ops$tkyte@ORA9IR2>

no we must get a 1555 - so go small:

ops$tkyte@ORA9IR2> create undo tablespace small datafile size 2m autoextend OFF;

Tablespace created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> drop table ora_1555;

Table dropped.

ops$tkyte@ORA9IR2> create table ora_1555 as select * from all_objects;

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter system set undo_tablespace = small;

System altered.


Now open a cursor -- it is read consistent as of NOW

ops$tkyte@ORA9IR2> variable x refcursor
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec open :x for select * from ora_1555;

PL/SQL procedure successfully completed.

generate lots of undo and commit and do it over again and again, ugly... don't do this
at home kids...

ops$tkyte@ORA9IR2> begin
2 for i in 1 .. 10
3 loop
4 loop
5 delete from ora_1555 where rownum <= 1000;
6 exit when sql%rowcount = 0;
7 commit;
8 end loop;
9 commit;
10 insert into ora_1555 select * from all_objects;
11 commit;
12 end loop;
13 end;
14 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA9IR2> print x
ERROR:
ORA-01555: snapshot too old: rollback segment number 13 with name "_SYSSMU13$" too small



no rows selected

got the error, and....

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter system set undo_tablespace = undo;

System altered.

ops$tkyte@ORA9IR2> drop tablespace small;

Tablespace dropped.

ops$tkyte@ORA9IR2> drop trigger snapshot_too_old;

Trigger dropped.

ops$tkyte@ORA9IR2> spool off
ops$tkyte@ORA9IR2> select * from t;

MSG
------------------------------------------------------------------------------------------
-------------------------------
ora_sysevent = SERVERERROR
ora_login_user = OPS$TKYTE
ora_server_error = 1555
l_sql_text(1) = SELECT * FROM ORA_1555

we have the record of it


Isn't a nice idea?
With this idea I remembered that I have ever writen one triger for one of my oversea's colleague requirement,he got an strange requirement that every owner mustn't get any privilege to execute any DDL, I tested several other ways but no one works, and suddenly I got the idea maybe triggers can help.
here is the code:
-- Please executing this script by user sys
CREATE OR REPLACE TRIGGER trg_deny_ddl
BEFORE DDL ON DATABASE
BEGIN
-- if the DDL fired by TEST1, just abort it
IF USER = 'TEST1'
THEN
raise_application_error (-20000,'user: '||USER||' are NOT permited for executing DDL!');
END IF;
END;
/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9728406/viewspace-916001/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9728406/viewspace-916001/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值