admin

如何使用触发器刷新实例化视图?

sql

create or replace TRIGGER REFRESH_REST_VIEW
AFTER
INSERT OR UPDATE
ON tbl_contract
BEGIN
execute DBMS_MVIEW.REFRESH(‘REST_VIEW’);
END REFRESH_REST_VIEW;
commit;

这是我用来刷新实例化视图的SQL触发器。但它说..

Warning: execution completed with warning
TRIGGER REFRESH_REST_VIEW Compiled.

PS:当表的数据(由Materialized View使用)进行任何DML操作时,将执行触发器。

我已经在Google上搜索了足够多的内容,很多帖子都说有可能,但我没有做到这一点。我尝试使用常规的触发器语法,但它不起作用。

更新:

现在,我尝试使用“过程”和“触发器”进行相同操作。

create or replace
PROCEDURE Rfresh_mate_views AS
  BEGIN
   DBMS_MVIEW.REFRESH('REST_VIEW');
  END Rfresh_mate_views;


create or replace trigger refresh_company_mview
after insert or update ON BCD.BCD_COMPANY
begin
RFRESH_MATE_VIEWS(); 
end refresh_company_mview;

所有内容均已成功编译,但在表中进行更新时显示:

ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2449
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2429
ORA-06512: at "BCD.RFRESH_MATE_VIEWS", line 3
ORA-06512: at "BCD.REFRESH_COMPANY_MVIEW", line 2
ORA-04088: error during execution of trigger 'BCD.REFRESH_COMPANY_MVIEW'

阅读 134

收藏
2021-07-01

共1个答案

admin

在触发器中刷新实例化视图没有任何意义。

您可以通过删除单词来解决语法错误 EXECUTE

create or replace TRIGGER REFRESH_REST_VIEW
 AFTER
  INSERT OR UPDATE
 ON tbl_contract
BEGIN
    DBMS_MVIEW.REFRESH('REST_VIEW');
END REFRESH_REST_VIEW;

那将导致触发器被编译。但是,当您尝试执行INSERTUPDATE反对时tbl_contract,您将得到一个运行时错误,不允许您在触发器中提交,因为刷新实例化视图会隐式提交,并且您无法在触发器内部提交。

SQL> create table foo( col1 number );

Table created.

SQL> create materialized view mv_foo
  2  as
  3  select *
  4    from foo;

Materialized view created.

SQL> create trigger trg_foo
  2    after insert or update on foo
  3  begin
  4    dbms_mview.refresh( 'MV_FOO' );
  5  end;
  6  /

Trigger created.

SQL> insert into foo values( 1 );
insert into foo values( 1 )
            *
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2760
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2740
ORA-06512: at "SCOTT.TRG_FOO", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRG_FOO'

您可能会尝试通过破坏事务完整性并在自主事务中进行刷新来解决此问题。这样可以消除ORA-04092错误,但是物化视图不会包含作为事务的一部分插入或更新的未提交数据,该事务首先触发了触发器,从而破坏了刷新物化视图的整个目的。

正确的方法不是一开始就使用触发器。正确的方法是定义实例化视图以在commit–时刷新自身REFRESH FAST ON COMMIT。由于出现错误,您无法在实例ON COMMIT化视图上设置属性,因此,您需要查看《数据仓库指南》中列出的对快速刷新限制,并确保您的实例化视图应可快速刷新。然后,您可以使用dbms_mview.explain_mview过程来告诉您,为何物化视图不符合提交时增量刷新的条件。

2021-07-01