2011-02-10 72 views
3

在Oracle DB中是否可以在VIEW上创建语句触发器(但不是行触发器)?在Oracle的VIEW中触发语句

当我在视图上创建INSTEAD OF触发器而没有FOR EACH ROW选项时,Oracle会以任何方式触发每行的触发器。

例如,下列代码:

CREATE TABLE TEST_TABLE (
    MY_DATA VARCHAR(30) 
); 

INSERT INTO TEST_TABLE(MY_DATA) VALUES('one'); 
INSERT INTO TEST_TABLE(MY_DATA) VALUES('two'); 
INSERT INTO TEST_TABLE(MY_DATA) VALUES('three'); 

CREATE OR REPLACE VIEW TEST_VIEW AS 
    SELECT * FROM TEST_TABLE; 

CREATE OR REPLACE TRIGGER TEST_VIEW_TRG1 
    INSTEAD OF DELETE ON TEST_VIEW 
DECLARE 
BEGIN 
    Dbms_Output.Put_Line('STATEMENT TRIGGER.'); 
END; 
/

CREATE OR REPLACE TRIGGER TEST_VIEW_TRG2 
    INSTEAD OF DELETE ON TEST_VIEW FOR EACH ROW 
DECLARE 
BEGIN 
    Dbms_Output.Put_Line('ROW TRIGGER: '||:OLD.MY_DATA); 
END; 
/

DELETE FROM TEST_VIEW; 

产生以下输出:

ROW TRIGGER: one 
STATEMENT TRIGGER. 
ROW TRIGGER: two 
STATEMENT TRIGGER. 
ROW TRIGGER: three 
STATEMENT TRIGGER. 

当我创建触发器TEST_VIEW_TRG1TEST_VIEW_TRG2AFTER上(而不是TEST_VIEW)一个TEST_TABLE输出如预期的那样:

ROW TRIGGER: one 
ROW TRIGGER: two 
ROW TRIGGER: three 
STATEMENT TRIGGER. 

这个问题有什么解决方法吗?

回答

9

INSTEAD OF触发器在视图上总是排为主,如在文件中指出:http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7004.htm#i2235611

FOR EACH ROW 指定每行指定触发器为一个行触发器。对于受触发语句影响的每一行,Oracle Database都会触发一次行触发器,并满足WHEN条件中定义的可选触发器约束。

除了INSTEAD OF触发器,如果​​你省略了这个子句,那么触发器就是一个语句触发器。如果满足可选的触发器约束条件,则在发出触发语句时,Oracle数据库仅触发一次语句触发器。

INSTEAD对每一行隐式激活触发器语句。