我有7个物化视图需要按计划刷新。
其中五个是独立于数据源的,可以异步重建。
其中两个依赖于前五个MView中的一些,需要等到刷新后再进行刷新。最后两个是相互独立的,可以异步运行。
我最初问过这个问题here。我的计划是去DBMS_JOB.SUBMIT路线。有人向我解释过,DBMS_JOB.SUBMIT是一个解决这个问题的Oracle 8级方法,我应该考虑使用DBMS_SCHEDULER。
我的问题变为:在Oracle 11g中进行同步和异步MView刷新的更好方法是什么?
我想分享我用过的DBMS_SCHEDULER解决方案,以防任何人对在Oracle 11g中使用同步和异步方法调用的更好方法感兴趣。
答案 0 :(得分:2)
TLDR:
代码:
-- First: Create the programs to refresh the MViews
BEGIN
-- Independent Programs
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_I1',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''IndependentMView1'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the IndependentMView1 MView.',
enabled => TRUE) ;
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_I2',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''IndependentMView2'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the IndependentMView2 MView.',
enabled => TRUE) ;
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_I3',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''IndependentMView3'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the IndependentMView3 MView.',
enabled => TRUE) ;
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_I4',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''IndependentMView4'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the IndependentMView4 MView.',
enabled => TRUE) ;
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_I5',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''IndependentMView5'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the IndependentMView5 MView.',
enabled => TRUE) ;
-- Dependent Programs
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_D1',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''DependentMView1'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the DependentMView1 MView.',
enabled => TRUE) ;
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROGRAM_REFRESH_MVIEW_D2',
program_action => 'BEGIN DBMS_MVIEW.REFRESH(list => ''DependentMView2'', METHOD => ''C'') ; END;',
program_type => 'PLSQL_BLOCK',
number_of_arguments => 0,
comments => 'This Refreshes the DependentMView2 MView.',
enabled => TRUE) ;
END;
/
-- Next: Create the chain to control the refresh steps
BEGIN
DBMS_SCHEDULER.CREATE_CHAIN (
chain_name => 'REFRESH_MVIEWS_CHAIN',
rule_set_name => NULL,
evaluation_interval => NULL,
comments => 'Refresh the Materialized Views in the correct order.') ;
END;
/
-- Next: Create the steps used to call the programs to refresh the MViews.
-- Note: Referenced programs must be enabled.
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepI1', 'PROGRAM_REFRESH_MVIEW_I1') ;
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepI2', 'PROGRAM_REFRESH_MVIEW_I2') ;
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepI3', 'PROGRAM_REFRESH_MVIEW_I3') ;
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepI4', 'PROGRAM_REFRESH_MVIEW_I4') ;
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepI5', 'PROGRAM_REFRESH_MVIEW_I5') ;
-- stepD1 is dependent on IndependentMView1, IndependentMView2, IndependentMView3
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepD1', 'PROGRAM_REFRESH_MVIEW_D1') ;
-- stepD2 is dependent on IndependentMView1, IndependentMView4
DBMS_SCHEDULER.DEFINE_CHAIN_STEP ('REFRESH_MVIEWS_CHAIN', 'stepD2', 'PROGRAM_REFRESH_MVIEW_D2') ;
END;
/
-- Next: Define rules for the chain. This is where we establish the
-- synchronous and asynchronous order of things. (i.e. where the magic happens)
BEGIN
-- First, start all independent steps asynchronously
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('REFRESH_MVIEWS_CHAIN', 'TRUE', 'START stepI1, stepI2, stepI3, stepI4, stepI5') ;
-- Next, start dependent steps as their related independent steps complete.
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('REFRESH_MVIEWS_CHAIN', 'stepI1 COMPLETED AND stepI2 COMPLETED AND stepI3 COMPLETED', 'START stepD1') ;
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('REFRESH_MVIEWS_CHAIN', 'stepI1 COMPLETED AND stepI4 COMPLETED', 'Start stepD2') ;
-- Last, define when the chain is complete.
-- In this case, we're done when both dependent steps and the one independent step that no other steps are dependent upon are all complete.
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('REFRESH_MVIEWS_CHAIN', 'stepI5 COMPLETED AND stepD1 COMPLETED AND stepD2 COMPLETED', 'END') ;
-- Enable the chain
DBMS_SCHEDULER.ENABLE ('REFRESH_MVIEWS_CHAIN') ;
END;
/
-- Next: create a schedule to run every 30 minutes at the top and bottom of every hour
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'THIRTY_MINUTE_SCHEDULE',
repeat_interval => 'FREQ=MINUTELY;INTERVAL=30',
start_date => TO_TIMESTAMP_TZ ('2015-11-2 0:0:00.000000000 UTC', 'YYYY-MM-DD HH24:MI:SS.FF TZR'),
comments => 'Fires at the top and bottom of every hour') ;
END;
/
-- Lastly: Create a job to start the REFRESH_MVIEWS_CHAIN chain based on the THIRTY_MINUTE_SCHEDULE created above.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'REFRESH_MVIEWS_JOB',
job_type => 'CHAIN',
job_action => 'REFRESH_MVIEWS_CHAIN',
schedule_name => 'TEN_TILL_TOP_BOTTOM_SCHEDULE',
number_of_arguments => 0,
enabled => FALSE,
auto_drop => FALSE,
comments => 'Refresh the Materialized Views');
DBMS_SCHEDULER.SET_ATTRIBUTE (
name => 'REFRESH_MVIEWS_JOB',
attribute => 'logging_level',
value => DBMS_SCHEDULER.LOGGING_OFF) ;
-- Enable the refresh job
DBMS_SCHEDULER.ENABLE (name => 'REFRESH_MVIEWS_JOB') ;
END;
/
沿途有用的链接: