当系统中存在多个物化视图,使用刷新组会大大简化物化视图的刷新,只需要将同一时间同步的物化视图全都放到一个刷新组中既可。
在9i中,使用刷新组方便的时候有一个缺点,如果其中一个物化视图报错,Oracle给出的错误信息并没有说明是哪个物化视图出了问题。
这篇文章讨论对于本地物化视图,如何定位刷新组中刷新失败的物化视图。
先构造一个简单的例子:
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for Linux: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。
SQL> CREATE TABLE T1 (ID PRIMARY KEY, NAME) AS SELECT ROWNUM, TNAME FROM TAB;
表已创建。
SQL> CREATE TABLE T2 (ID PRIMARY KEY, NAME) AS SELECT ROWNUM, TNAME FROM TAB;
表已创建。
SQL> CREATE TABLE T3 (ID PRIMARY KEY, NAME) AS SELECT ROWNUM, TNAME FROM TAB;
表已创建。
SQL> CREATE MATERIALIZED VIEW LOG ON T1;
实体化视图日志已创建。
SQL> CREATE MATERIALIZED VIEW LOG ON T2;
实体化视图日志已创建。
SQL> CREATE MATERIALIZED VIEW LOG ON T3;
实体化视图日志已创建。
SQL> CREATE MATERIALIZED VIEW MV_T1 REFRESH FAST AS SELECT * FROM T1;
实体化视图已创建。
SQL> CREATE MATERIALIZED VIEW MV_T2 REFRESH FAST AS SELECT * FROM T2;
实体化视图已创建。
SQL> CREATE MATERIALIZED VIEW MV_T3 REFRESH FAST AS SELECT * FROM T3;
实体化视图已创建。
SQL> EXEC DBMS_REFRESH.MAKE('REP_TEST', 'MV_T1,MV_T2,MV_T3', SYSDATE, 'SYSDATE 1')
PL/SQL 过程已成功完成。
SQL> INSERT INTO T1 VALUES (100, 'A');
IXDBA.NET社区论坛已创建 1 行。
SQL> INSERT INTO T2 VALUES (100, 'A');
已创建 1 行。
SQL> INSERT INTO T3 VALUES (100, 'A');
已创建 1 行。
SQL> EXEC DBMS_REFRESH.REFRESH('REP_TEST')
PL/SQL 过程已成功完成。
如果对表T2进行了修改:
SQL> ALTER TABLE T2 MODIFY NAME VARCHAR2(32);
表已更改。
SQL> INSERT INTO T1 VALUES (101, 'B');
已创建 1 行。
SQL> INSERT INTO T2 VALUES (101, LPAD('B', 32, 'B'));
已创建 1 行。
SQL> INSERT INTO T3 VALUES (101, 'B');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT MVIEW_NAME, LAST_REFRESH_DATE, STALENESS FROM USER_MVIEWS;
MVIEW_NAME LAST_REFRESH_DATE STALENESS
------------------------------ ------------------- -------------------
MV_T1 2008-01-23 19:22:43 NEEDS_COMPILE
MV_T2 2008-01-23 19:22:43 NEEDS_COMPILE
MV_T3 2008-01-23 19:22:43 NEEDS_COMPILE
SQL> EXEC DBMS_REFRESH.REFRESH('REP_TEST')
BEGIN DBMS_REFRESH.REFRESH('REP_TEST'); END;
*第 1 行出现错误:
ORA-12008: 实体化视图的刷新路径中存在错误
ORA-01401: 插入的值对于列过大
ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 794
ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 851
ORA-06512: 在"SYS.DBMS_IREFRESH", line 683
ORA-06512: 在"SYS.DBMS_REFRESH", line 195
ORA-06512: 在line 1
这时就会出现刷新错误,而Oracle给出的错误信息虽然很明确,但是并没有指出具体是那张表出现了错误,而只有找到错误的表才能定位并解决问题。
其实这个问题的解决方法有很多,比如写一个过程,对刷新组中所有的物化视图进行依次刷新,出现错误时弹出异常。也可以利用