Oracle 中 VIEW 上的语句触发器
Oracle DB 是否可以在 VIEW
上创建语句触发器(但不能创建行触发器)?
当我在视图上创建没有 FOR EACH ROW
选项的 INSTEAD OF
触发器时,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_TABLETEST_VIEW_TRG1
和 TEST_VIEW_TRG2
作为 AFTER
时code> (而不是 TEST_VIEW
)输出符合预期:
ROW TRIGGER: one
ROW TRIGGER: two
ROW TRIGGER: three
STATEMENT TRIGGER.
此问题有任何解决方法吗?
Is it possible in Oracle DB to create Statement trigger (but not Row trigger) on a VIEW
?
When I create INSTEAD OF
trigger without FOR EACH ROW
option on a view, Oracle fires that trigger for each row any way.
For example, the following code:
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;
Produces the following output:
ROW TRIGGER: one
STATEMENT TRIGGER.
ROW TRIGGER: two
STATEMENT TRIGGER.
ROW TRIGGER: three
STATEMENT TRIGGER.
When I create triggers TEST_VIEW_TRG1
and TEST_VIEW_TRG2
as AFTER
on a TEST_TABLE
(instead of a TEST_VIEW
) the output is as expected:
ROW TRIGGER: one
ROW TRIGGER: two
ROW TRIGGER: three
STATEMENT TRIGGER.
Is there any workaround for this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
视图上的触发器始终是基于行的,如文档中所述: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7004.htm#i2235611
对于每一行
指定 FOR EACH ROW 将触发器指定为行触发器。 Oracle 数据库为受触发语句影响并满足 WHEN 条件中定义的可选触发器约束的每一行触发一次行触发器。
除 INSTEAD OF 触发器外,如果省略该子句,则该触发器是语句触发器。如果满足可选触发器约束,Oracle 数据库仅在发出触发语句时触发语句触发器一次。
INSTEAD OF 触发器语句对每一行隐式激活。
INSTEAD OF Triggers on views are always row-based, as stated in the Docs: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7004.htm#i2235611
FOR EACH ROW
Specify FOR EACH ROW to designate the trigger as a row trigger. Oracle Database fires a row trigger once for each row that is affected by the triggering statement and meets the optional trigger constraint defined in the WHEN condition.
Except for INSTEAD OF triggers, if you omit this clause, then the trigger is a statement trigger. Oracle Database fires a statement trigger only once when the triggering statement is issued if the optional trigger constraint is met.
INSTEAD OF trigger statements are implicitly activated for each row.