刷新嵌套的实例化视图时如何捕获错误

时间:2019-04-02 13:08:24

标签: oracle materialized-views

材料化视图“ MV_AMP”:

CREATE MATERIALIZED VIEW MV_AMP
  NOLOGGING
  BUILD IMMEDIATE
  REFRESH FORCE
  ON DEMAND
AS
Select a, b, c from amp;

依赖于“ MV_AMP”的材料化视图“ MV_BOT”:

CREATE MATERIALIZED VIEW MV_BOT
  NOLOGGING
  BUILD IMMEDIATE
  REFRESH FORCE
  ON DEMAND
AS
SELECT bot.x, bot.y, mv_amp 
FROM bot, mv_amp
WHERE bot.a = mv_amp.a;

并在mv_bot中创建唯一索引:

CREATE UNIQUE INDEX mv_bot_idx001 ON mv_bot(x, a);

视图和索引创建成功后,假设我添加一个重复值,由于唯一索引,在刷新mv_bot时会导致类似(dup_val_on_index)的错误。

因此,我使用nested = TRUE在MV_AMP(主视图)中进行刷新,并且Oracle没有引发错误:

BEGIN
  dbms_mview.refresh_dependent(number_of_failures => n_failures,
                                   list => 'MV_AMP',
                                   atomic_refresh => TRUE,
                                   nested => TRUE);

EXCEPTION
  WHEN
    OTHERS THEN
        -- it never reach this code
        dbms_output.put_line('Errors: '||SQLERRM);
END;

n_failures返回:0,并且永远不会到达异常内部的dbms_output。

当oracle尝试更新嵌套的MV并登录表时,我需要捕获错误。

使用Oracle 11g。

1 个答案:

答案 0 :(得分:1)

只有在实例化视图EXCEPTION中存在重复行的情况下,MV_BOT块才达到-情况并非如此。

您可能会问为什么;最有说服力的答案是,您还需要刷新实例化视图MV_AMP ,以便在MV_BOT的联接中获得dup。

在阅读dbms_mview.refresh_dependent的文档时,您必须从表AMP开始才能刷新两个MV(从MV_AMP开始仅刷新依赖的MV < / em> MV_BOT

测试用例

create table amp (
a number,
b number,
c number);

create table bot (
a number,
x number,
y number);

CREATE MATERIALIZED VIEW MV_AMP
  NOLOGGING
  BUILD IMMEDIATE
  REFRESH FORCE
  ON DEMAND
AS
Select a, b, c from amp;

CREATE MATERIALIZED VIEW MV_BOT
  NOLOGGING
  BUILD IMMEDIATE
  REFRESH FORCE
  ON DEMAND
AS
SELECT bot.x, bot.y, mv_amp.a 
FROM bot, mv_amp
WHERE bot.a = mv_amp.a;

CREATE UNIQUE INDEX mv_bot_idx001 ON mv_bot(x, a);

insert into amp(a,b,c) values(1,1,1);
insert into bot(a,x,y) values(1,1,1);
insert into bot(a,x,y) values(1,1,3);
commit;

DECLARE
  n_failures NUMBER;
BEGIN
  dbms_mview.refresh_dependent(number_of_failures => n_failures,
                                   list => 'AMP',
                                   atomic_refresh => TRUE,
                                   nested => TRUE);
   dbms_output.put_line('Failures: '||n_failures);                                                                
EXCEPTION
  WHEN
    OTHERS THEN
        dbms_output.put_line('Errors: '||SQLERRM);
END;
/

--> Errors: ORA-12008: error in materialized view refresh path
--> ORA-00001: unique constraint (xxxxx.MV_BOT_IDX001) violated