Oracle 中 VIEW 上的语句触发器

发布于 2024-10-16 13:36:10 字数 1242 浏览 1 评论 0原文

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_TRG1TEST_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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白馒头 2024-10-23 13:36:10

视图上的触发器始终是基于行的,如文档中所述: 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文