记录一些工作中用到的 Oracle 触发器。
例1:记录会话 IP
CREATE OR REPLACE TRIGGER sys.tr_logon_ipAFTER logon ON DATABASEBEGINdbms_application_info.set_client_info(sys_context('USERENV','IP_ADDRESS'));END;
说明:
此触发器会在用户连接数据库时,记录访问者IP,并将访问者IP写入 v$session 的 client_info 字段。

需要注意的是,此触发器是否生效还与初始化参数 _system_trig_enabled 是否启用有关,如果参数为 FALSE,则系统触发器不生效。

例2:禁用DROP操作
在所有DDL操作中,DROP操作是比较危险的,最好是在DBA或管理员指导下进行。为防止误操作,比如不小心原本是加一列,结果点错了删掉一列,加一道保险。
触发器:
CREATE OR REPLACE Trigger TRG_DDL_DENY_DROPBefore Drop Or Truncate On DatabaseDeclarel_Errmsg Varchar2(100) := '删除对象之前请先与管理员联系';BeginIf Ora_Sysevent = 'DROP' And Ora_Dict_Obj_Owner ='YOURDB' ThenRaise_Application_Error(-20001, Ora_Dict_Obj_Owner || '.' || Ora_Dict_Obj_Name || ' ' || l_Errmsg);End If;ExceptionWhen No_Data_Found ThenNull;End;
在删除对象时,会报错:

临时需要DROP数据,可以禁用触发器,删完了再启用。
ALTER TRIGGER TRG_DDL_DENY_DROP DISABLE;DROP TABLE XXX;ALTER TRIGGER TRG_DDL_DENY_DROP ENABLE;
例3:自动生成主键列
将一个普通表转为含主键的表,并且主键是自动增长的,不用管主键数据,当插入数据时会自动添加主键。
首先需要创建一个自增的序列
create sequence SEQ_ID_XXXminvalue 1maxvalue 999999999start with 1;
然后对之前的表做改造,增加一列
alter table YOUR_TABLE add ID number(38);
使用序列,对这一列附值
update YOUR_TABLE set ID=SEQ_ID_XXX.nextval;commit;
添加触发器
create or replace trigger TRX_AUTO_XXX_IDbefore insert on YOUR_TABLEfor each rowbeginselect SEQ_ID_XXX.nextval into:new.ID from dual;end TRX_AUTO_XXX_ID;
最后对新列添加主键约束
alter table YOUR_TABLEadd constraint PK_YOU_TABLE_ID primary key (ID);
在工作中还经常会遇到经过 wrap 的存储过程或触发器,特别是一些恶意代码喜欢通过加密逃避风险检查,比如前几年常见的删库触发器,当数据库重启时并且库的生命周期超过300天就删库。
查看到如下经过 wrap 的存储过程

我们需要对其 unwrap 触密。wrap 是 Oracle 提供的加密工具,Oracle 并未提供 unwrap 工具。使用 wrap 并不能达到保护代码安全的目的,网上有线上 unwrap 工具可以用,我提供两个:
https://www.codecrete.net/UnwrapIt/
https://www.modb.pro/unwrap
将经过 wrap 的代码贴到网站中,处理完后的代码如下:

wrap 工具用法:
https://docs.oracle.com/database/121/LNPLS/wrap.htm




