WHEN trigger_condition
其中,trigger_condition是一个布尔表达式。每处理一行记录,都会重新判断该表达式的值。
也可以在trigger_condition内部使用:new和:old记录,但是与REFERENCING子句一样,在trigger_condition内部使用:new和:old时,不需要冒号。仅在触发器主体中才需要使用冒号。
5、触发器谓词
可以在触发器内部使用3个布尔函数,判断触发该触发器的到底是什么操作。这3个谓词分别是INSERTING、UPDATING和DELETING.
使用方法如下面这个例子所示
view plaincopy to clipboardprint
CREATE OR REPLACE TRIGGER LogInventoryChanges
BEFORE INSERT OR DELETE OR UPDATE ON inventory
FOR EACH ROW
DECLARE
v_ChangeType CHAR(1);
BEGIN
/* Use 'I' for an INSERT, 'D' for DELETE, and 'U' for UPDATE. */
IF INSERTING THEN
v_ChangeType := 'I';
ELSIF UPDATING THEN
v_ChangeType := 'U';
ELSE
v_ChangeType := 'D';
END IF;
/* Record all the changes made to inventory in
inventory_audit. Use SYSDATE to generate the timestamp, and
USER to return the userid of the current user. */
INSERT INTO inventory_audit
(change_type, changed_by, timestamp,
old_isbn, old_status, old_status_date, old_amount,
new_isbn, new_status, new_status_date, new_amount)
VALUES
(v_ChangeType, USER, SYSDATE,
:old.isbn, :old.status, :old.status_date, :old.amount,
:new.isbn, :new.status, :new.status_date, :new.amount);
END LogInventoryChanges;
/
CREATE OR REPLACE TRIGGER LogInventoryChanges
BEFORE INSERT OR DELETE OR UPDATE ON inventory
FOR EACH ROW
DECLARE
v_ChangeType CHAR(1);
BEGIN
/* Use 'I' for an INSERT, 'D' for DELETE, and 'U' for UPDATE. */
IF INSERTING THEN
v_ChangeType := 'I';
ELSIF UPDATING THEN
v_ChangeType := 'U';
ELSE
v_ChangeType := 'D';
END IF;
/* Record all the changes made to inventory in
inventory_audit. Use SYSDATE to generate the timestamp, and
USER to return the userid of the current user. */
INSERT INTO inventory_audit
(change_type, changed_by, timestamp,
old_isbn, old_status, old_status_date, old_amount,
new_isbn, new_status, new_status_date, new_amount)
VALUES
(v_ChangeType, USER, SYSDATE,
:old.isbn, :old.status, :old.status_date, :old.amount,
:new.isbn, :new.status, :new.status_date, :new.amount);
END LogInventoryChanges;
/
6、INSTEAD-OF触发器
INSTEAD-OF触发器仅可以定义在视图上(关系型的或对象),并且它们可以替代点火它们的DML语句进行点火。INSTEAD-OF触发器必须是行级的。
7、触发器的限制
触发器的主体是一个PL/SQL块。在PL/SQL块中可以使用的所有语句在触发器主体中都是合法的,但是要受到下面限制的约束:
触发器不应该使用事务控制语句—COMMIT、ROLLBACK或SAVEPOINT。触发器作为触发语句执行的一部分被点火,它和触发语句在同一个事务中。当触发语句被提交或撤回提交时,触发器的工作也相应被提交会撤回提交。
由触发器主体调用的任何过程和函数都不能使用事务控制语句。
触发器主体不能声明任何LONG或者LONG RAW变量。而且,:new和:old不能指向定义触发器的表中的LONG和LONG RAW列。
触发器主体可以访问的表有所限制。
触发器P-Code
当包或者子程序存储在数据字典中时,存储的除了该对象的源代码还有经过编译的p-code。但是对于触发器来说就不是这样的。在数据字典中唯一存储的是触发器的源代码,而不是p-code。结果,每次当从数据字典中重新读出触发器时,必须要进行编译。这对触发器的定义和使用的方式不会带来什么影响,但是会影响触发器的性能。
8、系统触发器
我们前面所看到的DML触发器和INSTEAD-OF触发器都是基于DML事件。而另一方面,系统触发器的激活则是基于两种不同的事件:DDL事件或数据库事件。DDL事件包括CREATE、ALTER或DROP语句,而数据库事件包括数据库服务器的启动/关闭事件,用户的登陆/断开事件,以及服务器错误。创建系统触发器的语法如下:
view plaincopy to clipboardprint
CREATE [OR REPLACE] TRIGGER [schema.]trigger_name
{BEFORE | AFTER}
{ddl_event_list | database_event_list}
ON {DATABASE | [schema.]SCHEMA}
[when_clause]
Trigger_body;
CREATE [OR REPLACE] TRIGGER [schema.]trigger_name
{BEFORE | AFTER}
{ddl_event_list | database_event_list}
ON {DATABASE | [schema.]SCHEMA}
[when_clause]
Trigger_body;
其中,ddl_event_list是由OR关键字隔开的一个或 个DDL事件,database_event_list则是由OR关键字隔开的一个或多个数据库事件。
注意:不能创建INSTEAD-OF系统级触发器。
通过子句ON {DATABASE | [schema.]SCHEMA}我们可以指定这个系统触发器是定义在数据库级上还是模式级上。只要发生了激活事件,数据库