刷新嵌套物化视图时如何捕获错误
How to catch errors when refresh nested materialized views
实体化视图"MV_AMP":
CREATE MATERIALIZED VIEW MV_AMP
NOLOGGING
BUILD IMMEDIATE
REFRESH FORCE
ON DEMAND
AS
Select a, b, c from amp;
实体化视图 "MV_BOT" 依赖于 "MV_AMP":
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 returns: 0 并且它永远不会到达异常内的 dbms_output。
我需要在 oracle 尝试更新嵌套 MV 并登录 table 时捕获错误。
使用 Oracle 11g。
只有在实体化视图中存在重复行的情况下才会到达 EXCEPTION
块 MV_BOT
- 事实并非如此。
你可能会问为什么;最有可能的答案是您还需要刷新物化视图MV_AMP
, 才能在 MV_BOT
.
的连接中获取 dup
在阅读 dbms_mview.refresh_dependent
的文档时您意识到,您必须从 table AMP
开始才能刷新两个 MV(从 MV_AMP
开始仅刷新依赖MV 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
实体化视图"MV_AMP":
CREATE MATERIALIZED VIEW MV_AMP
NOLOGGING
BUILD IMMEDIATE
REFRESH FORCE
ON DEMAND
AS
Select a, b, c from amp;
实体化视图 "MV_BOT" 依赖于 "MV_AMP":
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 returns: 0 并且它永远不会到达异常内的 dbms_output。
我需要在 oracle 尝试更新嵌套 MV 并登录 table 时捕获错误。
使用 Oracle 11g。
只有在实体化视图中存在重复行的情况下才会到达 EXCEPTION
块 MV_BOT
- 事实并非如此。
你可能会问为什么;最有可能的答案是您还需要刷新物化视图MV_AMP
, 才能在 MV_BOT
.
在阅读 dbms_mview.refresh_dependent
的文档时您意识到,您必须从 table AMP
开始才能刷新两个 MV(从 MV_AMP
开始仅刷新依赖MV 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