触发器的一般语法是:
?
CREATE OR REPLACE TRIGGER [sachema.]trigger_name
{BEFORE|AFTER}
{ddl_event_list | database_event_list}
ON { DATABASE | [schema.]SCHEMA }
[WHEN condition]
PL/SQL_block | CALL procedure_name;
?
?
其中: ddl_event_list:一个或多个DDL 事件,事件间用 OR 分开;
database_event_list:一个或多个数据库事件,事件间用 OR 分开;
?
系统事件触发器既可以建立在一个模式上,又可以建立在整个数据库上。当建立在模式(SCHEMA)之上时,只有模式所指定用户的DDL操作和它们所导致的错误才激活触发器, 默认时为当前用户模式。当建立在数据库(DATABASE)之上时,该数据库所有用户的DDL操作和他们所导致的错误,以及数据库的启动和关闭均可激活触发器。要在数据库之上建立触发器时,要求用户具有ADMINISTER DATABASE TRIGGER权限。
?
下面给出系统触发器的种类和事件出现的时机(前或后):
| 事件 |
允许的时机 |
说明 |
| STARTUP |
AFTER |
启动数据库实例之后触发 |
| SHUTDOWN |
BEFORE |
关闭数据库实例之前触发(非正常关闭不触发) |
| SERVERERROR |
AFTER |
数据库服务器发生错误之后触发 |
| LOGON |
AFTER |
成功登录连接到数据库后触发 |
| LOGOFF |
BEFORE |
开始断开数据库连接之前触发 |
| CREATE |
BEFORE,AFTER |
在执行CREATE语句创建数据库对象之前、之后触发 |
| DROP |
BEFORE,AFTER |
在执行DROP语句删除数据库对象之前、之后触发 |
| ALTER |
BEFORE,AFTER |
在执行ALTER语句更新数据库对象之前、之后触发 |
| DDL |
BEFORE,AFTER |
在执行大多数DDL语句之前、之后触发 |
| GRANT |
BEFORE,AFTER |
执行GRANT语句授予权限之前、之后触发 |
| REVOKE |
BEFORE,AFTER |
执行REVOKE语句收权限之前、之后触犯发 |
| RENAME |
BEFORE,AFTER |
执行RENAME语句更改数据库对象名称之前、之后触犯发 |
| AUDIT / NOAUDIT |
BEFORE,AFTER |
执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发 |
?
?
8.2.4 系统触发器事件属性
?
| 事件属性\事件 |
Startup/Shutdown |
Servererror |
Logon/Logoff |
DDL |
DML |
| 事件名称 |
ü* |
ü* |
ü* |
ü* |
* |
| 数据库名称 |
ü* |
? |
? |
? |
? |
| 数据库实例号 |
ü* |
? |
? |
? |
? |
| 错误号 |
? |
ü* |
? |
? |
? |
| 用户名 |
? |
? |
ü* |
* |
? |
| 模式对象类型 |
? |
? |
? |
ü* |
* |
| 模式对象名称 |
? |
? |
? |
ü* |
* |
| 列 |
? |
? |
? |
? |
ü* |
?
除DML语句的列属性外,其余事件属性值可通过调用ORACLE定义的事件属性函数来读取。
| 函数名称 |
数据类型 |
说 明 |
| Ora_sysevent |
VARCHAR2(20) |
激活触发器的事件名称 |
| Instance_num |
NUMBER |
数据库实例名 |
| Ora_database_name |
VARCHAR2(50) |
数据库名称 |
| Server_error(posi) |
NUMBER |
错误信息栈中posi指定位置中的错误号 |
| ? ? Is_servererror(err_number) |
? ? BOOLEAN |
检查err_number指定的错误号是否在错误信息栈中,如果在则返回TRUE,否则返回FALSE。在触发器内调用此函数可以判断是否发生指定的错误。 |
| Login_user |
VARCHAR2(30) |
登陆或注销的用户名称 |
| Dictionary_obj_type |
VARCHAR2(20) |
DDL语句所操作的数据库对象类型 |
| Dictionary_obj_name |
VARCHAR2(30) |
DDL语句所操作的数据库对象名称 |
| Dictionary_obj_owner |
VARCHAR2(30) |
DDL语句所操作的数据库对象所有者名称 |
| Des_encrypted_password |
VARCHAR2(2) |
正在创建或修改的经过DES算法加密的用户口令 |
?
例1:创建触发器,存放有关事件信息。
DESC ora_sysevent
DESC ora_login_user
--创建用于记录事件用的表
CREATE TABLE ddl_event
(crt_date timestamp PRIMARY KEY,
event_name VARCHAR2(20),
user_name VARCHAR2(10),
obj_type VARCHAR2(20),
obj_name VARCHAR2(20));
--创建触犯发器
CREATE OR REPLACE TRIGGER tr_ddl
AFTER DDL ON SCHEMA
BEGIN
INSERT INTO ddl_event VALUES
(systimestamp,ora_sysevent, ora_login_user,
ora_dict_obj_type, ora_dict_obj_name);
END tr_ddl;
?
?
例2:创建登录、退出触发器。
CREATE TABLE log_event
(user_name VARCHAR2(10),
address VARCHAR2(20),
logon_date timestamp,
logoff_date timestamp);
--创建登录触发器
CREATE OR REPLACE TRIGGER tr_logon
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logon_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logon;
--创建退出触发器
CREATE OR REPLACE TRIGGER tr_logoff
BEFORE LOGOFF ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logoff_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logoff;
?
?
8.2.5 使用触发器谓词
ORACLE 提供三个参数INSERTING, UPDATING,DELETING 用于判断触发了哪些操作。
| 谓词 |
行为 |
| INSERTING |
如果触发语句是 INSERT 语句,则为TRUE,否则为FALSE |
| UPDATING |
如果触发语句是 UPDATE语句,则为T |