【问题标题】:How to refresh materialized view using trigger?如何使用触发器刷新物化视图?
【发布时间】:2015-05-21 14:45:55
【问题描述】:
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.

附: : 当表(实体化视图使用)的数据进行任何DML操作时,触发器将被执行。

我已经用谷歌搜索了很多,很多帖子说这是可能的,但我不知道该怎么做。我尝试使用常规触发器语法,但它不起作用。

更新:

现在我正在尝试对过程和触发器进行相同的操作..

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'

【问题讨论】:

  • 为什么要在触发器中执行此操作?为什么不将物化视图声明为REFRESH FAST ON COMMIT,让Oracle在事务提交时自动刷新物化视图?
  • 谢谢 Cave,我试过了,它说.. SQL 错误:ORA-12054:无法为物化视图 12054 设置 ON COMMIT 刷新属性。00000 -“无法为物化视图” *原因:物化视图在提交时不满足刷新条件。 *操作:仅指定有效选项。

标签: sql oracle triggers oracle10g materialized-views


【解决方案1】:

在触发器中刷新物化视图没有意义。

您可以通过删除单词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;

这将导致触发器编译。但是,当您尝试针对tbl_contract 执行INSERTUPDATE 时,您现在将收到一个运行时错误,不允许您在触发器中提交,因为刷新物化视图会隐含提交,您不能在触发器内提交。

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 错误,但随后物化视图将不会包含作为首先触发触发器的事务的一部分插入或更新的未提交数据,这违背了刷新物化视图的整个目的。

正确的方法是一开始就不要使用触发器。正确的方法是定义物化视图以在提交时刷新自身——REFRESH FAST ON COMMIT。由于您收到无法在物化视图上设置ON COMMIT 属性的错误,因此您需要查看数据仓库指南中列出的restrictions on fast refresh 并确保您的物化视图应该是可快速刷新的.然后,您可以使用dbms_mview.explain_mview procedure 告诉您为什么物化视图不符合提交时增量刷新的条件。

【讨论】:

  • @manurajhada - 更新了什么问题?我没有看到您提出的问题的任何更新。
  • @manurajhada - 好的,现在我看到了编辑。看来您看到的正是我所说的,如果您更正了语法错误,您会看到。您不能在触发器中提交并刷新物化视图会发出隐式提交。在我最初的回答中,我谈到了如何使用自治事务来解决该错误,但是刷新将无法看到您的事务所做的更改,这不太可能是您想要的。我原来的答案是,你真的会想让物化视图在提交时刷新。
  • 明白了,非常感谢您提供的宝贵知识。我已经通过Asynchronous Java code 完成了刷新,因为这需要很多时间并且之前我的应用程序运行缓慢。
【解决方案2】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-09
    • 2021-07-16
    • 2017-06-07
    • 2012-07-18
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2021-11-11
    相关资源
    最近更新 更多