关于MV刷新的问题
2014-06-16 19:59
155 查看
关于MV刷新的问题
最近在工作中遇到一个问题,是关于物化视图的刷新的,对实际数据产生了比较大的影响。虽然犯得错误很低级,主要是由于对一些概念的不清晰造成的,但是仍然觉得有必要将这个问题记下来,以免悲剧再次发生。
这个错误还需要从materialized view的创建开始追溯,因为如果在create materialized view语句中加入start with 和 next 子句的话,创建MV的过程中会自动创建一个job,制定定期刷新计划,例如:
create materialized view t1_mv refresh fast
start with to_date('21-07-2009 17:15:00', 'dd-mm-yyyy hh24:mi:ss')
next TRUNC(SYSDATE,'HH')+375/1440
with primary key
as select * from t1;
SQL> select job, schema_user, interval, what from all_jobs;
JOB SCHEMA_USER INTERVAL WHAT
---------- ------------------ ----------------------------------- ----------------------------------------------
21 WANGXIAOQI TRUNC(SYSDATE,'HH')+375/1440 dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"');
SQL>
可以看到,这个job中的执行内容是:dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"'); 而不是我们普通手动刷新MV时用的 dbms_mview.refresh 。
再来研究一下dbms_refresh这个数据包,这个包是用于产生一个刷新组以方便MV一组为单位统一刷新的。而当MV被制定刷新策略的方式指定时,会自动创建一个刷新组,并将该MV添加至这个刷新组中,所以job可以使用dbms_refresh.refresh来进行刷新。可以来看一下:
SQL> select rowner, rname, job, interval from all_refresh where rname = 'T1_MV';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI T1_MV 21 TRUNC(SYSDATE,'HH')+375/1440
再看这个组的成员:
SQL> select rowner, rname, job, interval from all_refresh_children where rname = 'T1_MV';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI T1_MV 21 TRUNC(SYSDATE,'HH')+375/1440
可以看到只有这个物化视图本身。
所以当物化视图刷新脚本自动执行时,刷新的是你所创建的MV的名字命名的刷新组,而不是单纯得刷新这个MV。 注:关于具体如何使用dbms_refresh来创建刷新组、添加成员、进行刷新等操作,可以参见以下地址:http://www.lansz.com/html/2009/06/mview_step_by_step_05.html
这新一次的物化视图创建中,没有指定执行时间,而是单纯得创建,所以Oracle不会创建刷新组,如下:
SQL>
SQL> create materialized view t1_mv_2 refresh fast
2 as select * from t1;
Materialized view created
SQL> select rowner, rname, job, interval from all_refresh_children where rname = 'T1_MV_2';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
SQL>
所以,如果对dbms_refresh了解不清的情况下,会造成无法刷新的情况,如果对没有创建刷新组的对象进行刷新就报错:
SQL> exec dbms_refresh.refresh('T1_MV_2');
begin dbms_refresh.refresh('T1_MV_2'); end;
ORA-23404: refresh group "WANGXIAOQI"."T1_MV_2" does not exist
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: at "SYS.DBMS_REFRESH", line 23
ORA-06512: at "SYS.DBMS_REFRESH", line 195
ORA-06512: at line 2
SQL> exec dbms_mview.refresh('T1_MV_2');
PL/SQL procedure successfully completed
另外还需要注意一点,如果删除了某个MV,则会连同创建的fresh group同时删除,需要在实际操作中注意。
最近在工作中遇到一个问题,是关于物化视图的刷新的,对实际数据产生了比较大的影响。虽然犯得错误很低级,主要是由于对一些概念的不清晰造成的,但是仍然觉得有必要将这个问题记下来,以免悲剧再次发生。
这个错误还需要从materialized view的创建开始追溯,因为如果在create materialized view语句中加入start with 和 next 子句的话,创建MV的过程中会自动创建一个job,制定定期刷新计划,例如:
create materialized view t1_mv refresh fast
start with to_date('21-07-2009 17:15:00', 'dd-mm-yyyy hh24:mi:ss')
next TRUNC(SYSDATE,'HH')+375/1440
with primary key
as select * from t1;
SQL> select job, schema_user, interval, what from all_jobs;
JOB SCHEMA_USER INTERVAL WHAT
---------- ------------------ ----------------------------------- ----------------------------------------------
21 WANGXIAOQI TRUNC(SYSDATE,'HH')+375/1440 dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"');
SQL>
可以看到,这个job中的执行内容是:dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"'); 而不是我们普通手动刷新MV时用的 dbms_mview.refresh 。
再来研究一下dbms_refresh这个数据包,这个包是用于产生一个刷新组以方便MV一组为单位统一刷新的。而当MV被制定刷新策略的方式指定时,会自动创建一个刷新组,并将该MV添加至这个刷新组中,所以job可以使用dbms_refresh.refresh来进行刷新。可以来看一下:
SQL> select rowner, rname, job, interval from all_refresh where rname = 'T1_MV';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI T1_MV 21 TRUNC(SYSDATE,'HH')+375/1440
再看这个组的成员:
SQL> select rowner, rname, job, interval from all_refresh_children where rname = 'T1_MV';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI T1_MV 21 TRUNC(SYSDATE,'HH')+375/1440
可以看到只有这个物化视图本身。
所以当物化视图刷新脚本自动执行时,刷新的是你所创建的MV的名字命名的刷新组,而不是单纯得刷新这个MV。 注:关于具体如何使用dbms_refresh来创建刷新组、添加成员、进行刷新等操作,可以参见以下地址:http://www.lansz.com/html/2009/06/mview_step_by_step_05.html
这新一次的物化视图创建中,没有指定执行时间,而是单纯得创建,所以Oracle不会创建刷新组,如下:
SQL>
SQL> create materialized view t1_mv_2 refresh fast
2 as select * from t1;
Materialized view created
SQL> select rowner, rname, job, interval from all_refresh_children where rname = 'T1_MV_2';
ROWNER RNAME JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
SQL>
所以,如果对dbms_refresh了解不清的情况下,会造成无法刷新的情况,如果对没有创建刷新组的对象进行刷新就报错:
SQL> exec dbms_refresh.refresh('T1_MV_2');
begin dbms_refresh.refresh('T1_MV_2'); end;
ORA-23404: refresh group "WANGXIAOQI"."T1_MV_2" does not exist
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: at "SYS.DBMS_REFRESH", line 23
ORA-06512: at "SYS.DBMS_REFRESH", line 195
ORA-06512: at line 2
SQL> exec dbms_mview.refresh('T1_MV_2');
PL/SQL procedure successfully completed
另外还需要注意一点,如果删除了某个MV,则会连同创建的fresh group同时删除,需要在实际操作中注意。
相关文章推荐
- 关于树型的刷新问题
- 关于使用了透明文字背景后,文字不能刷新而重叠在一起的问题
- 关于gridview插入数据后,不能同步刷新的问题
- 关于delphi中控件刷新时带来的闪烁问题(gif),转自别人的解决方法描述。
- [Silverlight学习笔记]关于页面刷新的问题
- 关于excel表格刷新问题
- 关于页面刷新的问题
- 关于UpdatePanel和页面刷新的问题
- Help!!关于图形图象控件的刷新问题
- 关于Child风格的CDialog上CListCtrl, 在CDialog最小化或者有窗口遮挡后CListCtrl无法刷新的问题
- 关于父框架刷新问题
- 3-(E-Teller)关于删除记录后不刷新的问题
- 关于页面刷新的问题
- 关于ItemRenderer刷新改变值的问题
- 关于子窗口关闭同时刷新父窗口问题详解
- 关于DDL控件提交后刷新问题
- 关于页面刷新的问题
- 关于更换验证码图片不刷新页面问题
- 关于history.back()后,页面刷新的问题
- 关于DropDownList无刷新联动的问题