------------------------------------------------------觸發器做審計、系統觸發器----------------------------------------------------------------------------------------------
系統級觸發器 觸發事件表:
觸發器事件 觸發時間
觸發條件
Logon After
用戶登錄成功後
Logoff Before
用戶退出登錄前
Startup After
數據庫啓動後
Shutdown Before數據庫關閉前
Servererror After系統發生故障後
Logon/Logoff觸發器可以用來記錄用戶登入和退出的時間。
數據庫啓動和關閉觸發器可以用來進行一些數據庫啓動後和關閉前的前處理和後處理。
Servererror觸發器可以用於記錄某些重要的錯誤信息,以便於跟蹤系統,發現故障。
觸發器
1、DML審計,記錄到日誌表 ; 阻止DML操作,拋出異常
2、系統觸發器:審計用戶登錄、退出、啓庫、停庫、系統錯誤等
3、DDL觸發器禁止用戶DDL
1、DML審計,記錄到日誌表 ; 阻止DML操作,拋出異常
①DML審計,記錄到日誌表 ;(當然我也可以用FGA見點擊打開鏈接)
create table t2 as select * from emp;
create table aud_tmp(exec_time date,exec_type varchar2(10),exec_user varchar2(20));
create or replace trigger tri_t2_after_row
after update or insert or delete
on t2 for each row
begin
if updating then
insert into aud_tmp values(sysdate,'update',SYS_context('USERENV','CURRENT_USER'));
elsif inserting then
insert into aud_tmp values(sysdate,'insert',SYS_context('USERENV','CURRENT_USER'));
else
insert into aud_tmp values(sysdate,'delete',SYS_context('USERENV','CURRENT_USER'));
end if;
end;
②禁止DML操作T1表 觸發器直接拋出錯誤中斷DML操作
create or replace trigger tr_no_dml before update or delete or insert on t1
begin
if updating
then
raise_application_error(-20001,'不允許做UPDATE操作!');
elsif inserting
then
raise_application_error(-20002,'不允許做insert操作!');
else
raise_application_error(-20003,'不允許做delete操作!');
end if;
end;
2、系統觸發器:審計用戶登錄、退出、啓庫、停庫、系統錯誤等
創建記錄日誌的表
CREATE TABLE log_audit (
login_date DATE,
logoff_date date,
username VARCHAR2(20),
user_ip varchar2(20),
error_code varchar2(15)
);
①審計用戶登錄、退出
----logon/logoff on database只能在sys用戶下做
create or replace TRIGGER logon_audit AFTER LOGON ON DATABASE
BEGIN
if user not in ('SYS','SYSMAN')
then
insert into log_audit(login_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
end if;
END;
create or replace TRIGGER logoff_audit BEFORE LOGOFF ON DATABASE
BEGIN
if user not in ('SYS','SYSMAN')
THEN
insert into log_audit (logoff_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
end if;
END;
②審計停庫
create table log_table(sid number,
serial# number,
username varchar2(30),
action varchar2(8),
log_time varchar2(19));
create or replace trigger dbshutdown
before shutdown on database
declare
v_sid v$mystat.sid%type;
v_serial# v$session.serial#%type;
v_username v$session.username%type;
begin
select sid into v_sid from v$mystat where rownum=1;
select serial#,username
into v_serial#,v_username
from v$session
where sid=v_sid;
insert into scott.log_table
values (v_sid,v_serial#,v_username,'ShutDown',to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
end dbshutdown;
③錯誤跟蹤的觸發器
CREATE OR REPLACE TRIGGER log_errors AFTER SERVERERROR ON DATABASE
BEGIN
IF (IS_SERVERERROR (1017)) THEN
insert into log_audit (login_date,USERNAME,USER_IP,error_code) values(sysdate,ora_login_user,ora_client_ip_address,'ORA-1017');
ELSIF (IS_SERVERERROR (2449)) THEN
insert into log_audit (login_date,USERNAME,USER_IP,error_code) values(sysdate,ora_login_user,ora_client_ip_address,'ORA-2449');
END IF;
END;
3、DDL觸發器禁止用戶做DDL(不能做在sys上 只能拿普通用戶做)
-------------------------------------------------------------------------------------------
create or replace trigger DDL_TR
before alter or drop or rename on schema
begin
raise_application_error(-20030,'系統正在運行,不能做DDL,別搗亂!');
end;
附:
系統事件函數:
函數名稱 類型
描述
ora_client_ip_address
VARCHAR2 客戶端的IP地址
ora_database_name
VARCHAR2(50) 數據庫名稱
ora_dict_obj_name
VARCHAR2(30) DDL發生的對象名稱
ora_dict_obj_owner
VARCHAR2(30) DDL發生對象的宿主
ora_dict_obj_type
VARCHAR2(20) 對象類別
ora_is_alter_column(column_name IN VARCHAR2)
BOOLEAN 當某列被修改的時候返回真,否則返回假
ora_is_drop_column(column_name IN VARCHAR2)
BOOLEAN 當某列被刪除的時候返回真,否則返回假
ora_login_user
VARCHAR2(30) 登錄的用戶名
ora_sysevent VARCHAR2(20) 系統事件的名稱
is_servererror(error_num in integer)
BOLEAN返回系統是否產生某個錯誤
ORACLE 8I開始,提供了一個新的函數“SYS_CONTEXT”。
通過使用SYS_CONTEXT函數可以獲得一些和用戶相關的信息,比如:
SELECT sys_context('USERENV','TERMINAL') FROM DUAL;
用戶環境的取值包括:
TERMINAL: 客戶端操作系統終端的名稱
LANGUAGE: NLS_LANG的值
LANG : ISO字符集的名稱.
SESSIONID: SESSION的ID
INSTANCE: 實例的ID
ISDBA: 是否具有DBA權限
CLIENT_INFO: 64字節的用戶信息,可以用DBMS_APPLICATION_INFO設置的值:
NLS_TERRITORY:當前SESSION的 territory
NLS_CURRENCY: 當前SESSION的貨幣符
NLS_CALENDAR: 當前SESSION的歷法
NLS_DATE_FORMAT:當前SESSION的日期格式
NLS_DATE_LANGUAGE :顯示日期的語言
NLS_SORT:排序方式(BINARY 或者linguistic)
CURRENT_USER:當前SESSION擁有權限的用戶的名稱(比如說當前SESSION是SYS,但是正在執行system.myproc,那麼current_user就是system)
CURRENT_USERID :當前SESSION擁有的權限的用戶的ID
SESSION_USER:session所屬的用戶名
SESSION_USERID:當前SESSION所屬的用戶id
CURRENT_SCHEMA:當前SESSION缺省的SCHEMA名稱,可以用SESSION SET CURRENT_SCHEMA 語句修改.
CURRENT_SCHEMAID :當前SESSION缺省的SCHEMA的ID
PROXY_USER:打開當前SESSION的用戶的名稱
PROXY_USERID:打開當前SESSION的用戶的ID
DB_DOMAIN:當前數據庫的DOMAIN
DB_NAME:當前數據庫的名稱
HOST:客戶端的主機名稱
OS_USER:客戶端的操作系統用戶名
EXTERNAL_NAME:用戶的外部名稱。對於SSL用戶,使用v.503協議,返回的值是證書中的DN
IP_ADDRESS:客戶端的IP地址
NETWORK_PROTOCOL:連接串中的PROTOCOL=protocol指明的網絡協議
BG_JOB_ID :如果當前的SESSION是由ORACLE後臺進程啓動的,那麼返回JOB_ID,否則返回空值
FG_JOB_ID:如果當前SESSION是由ORACLE客戶端進程啓動的一個JOB,那麼返回JOB_ID,否則返回空值
AUTHENTICATION_TYPE:返回數據庫鑑權的方法,返回值包括:
DATABASE: 使用數據庫的用戶名口令
OS:使用操作系統外部用戶鑑權
NETWORK:網絡鑑權
PROXY:OCI的代理連接鑑權
AUTHENTICATION_DATA:使用X.503證書鑑權的時候,返回HEX2的證書