重命名查询中使用的 table 时实例化视图无效。 ORA-00942 和 ORA-06512,甲骨文 19c

invalid materialized view when renaming a table used in the its query. ORA-00942 and ORA-06512, oracle 19c

我正在尝试替换物化视图使用的 table 并将其替换为同义词。 mview 变得无效,需要删除并重新创建才能使其工作。有没有其他方法可以在不删除 mview 的情况下修复它?

-- create test for issue with materialized views
create table tab_20211101 (first_name varchar2(100) primary key );
insert into tab_20211101 (first_name) values ('abc');
commit;
create materialized view log on tab_20211101 with rowid, primary key including new values;
create materialized view tab_20211101_mv refresh fast on commit as select * from tab_20211101;
select * from tab_20211101_mv;

-- now rename the table
drop materialized view log on tab_20211101;
alter table tab_20211101 rename to tab_20211101_new_name;
create materialized view log on tab_20211101_new_name with rowid, primary key including new values;

-- materialized view is now invalid, makes sense
select * from USER_OBJECTS a where a.OBJECT_NAME like 'TAB_20211101%' and STATUS = 'INVALID';
create synonym tab_20211101 for tab_20211101_new_name;

-- mv query works
select * from tab_20211101
-- materialized view still invalid, hmmm
select * from USER_OBJECTS a where a.OBJECT_NAME like 'TAB_20211101%' and STATUS = 'INVALID';

/*
 cannot refresh with ugly error
ORA-00942: table or view does not exist
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3020
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 2432
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 88
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 253
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 2413
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 2976
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3263
ORA-06512: at "SYS.DBMS_SNAPSHOT_KKXRCA", line 3295
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 16
 */
begin
    DBMS_MVIEW.REFRESH('TAB_20211101_MV');
end;

drop materialized view tab_20211101_mv;
create materialized view tab_20211101_mv refresh fast on commit as select * from tab_20211101;
-- mview is now valid
select * from USER_OBJECTS a where a.OBJECT_NAME like 'TAB_20211101%' and STATUS = 'INVALID';


编辑 2021.11.01 13:02:类似的策略似乎适用于同义词

create table tab_20211101 (a int primary key);
create synonym tab_20211101_syn for tab_20211101;
select * from tab_20211101_syn; -- OK
alter table tab_20211101 rename to tab_20211101_new;
select * from tab_20211101_syn; -- ORA-00980: synonym translation is no longer valid
create synonym tab_20211101 for tab_20211101_new;
select * from tab_20211101_syn; -- OK

不能,因为对象 ID 已更改。在您的情况下,除非您重新创建 MVIEW,否则同义词将不起作用。即使 COMPILE 实体化视图也会将状态更改为 VALID 但事务将不起作用。

此演示仅涵盖以下场景:您有一个 table、上面有一个实体化视图日志,以及一个具有快速刷新的实体化视图

演示(Oracle 19c)

SQL> create table test.t2 ( c1 number, c2 number ) ;

Table created.

SQL> create materialized view log on test.t2 ;

Materialized view log created.

SQL> create materialized view test.mv_t2 refresh fast on commit as select * from test.t2 ;

Materialized view created.

SQL> select * from test.mv_t2 ;

        C1         C2
---------- ----------
         1          1
         2          2
         3          3

现在,让我们删除 MLog,重命名 table 并创建 synonym

SQL> drop materialized view log on test.t2 ;

Materialized view log dropped.

SQL> alter table test.t2 rename to t2_old ;

Table altered.

SQL> create or replace synonym test.t2 for test.t2_old ;

Synonym created.

重新创建日志后,实体化视图无效

SQL> create materialized view log on t2_old ;

Materialized view log created.

SQL> select object_name , status from user_objects where object_name = 'MV_T2' ;

OBJECT_NAME
--------------------------------------------------------------------------------
STATUS
-------
MV_T2
VALID

MV_T2
INVALID

编译后

SQL> alter materialized view test.mv_t2 compile ;

Materialized view altered.

SQL> select object_name , status from user_objects where object_name = 'MV_T2' ;

OBJECT_NAME
--------------------------------------------------------------------------------
STATUS
-------
MV_T2
VALID

但是,如果我想插入

SQL>  insert into test.t2 values ( 4 ,4 ) ;

1 row created.

SQL>  commit ;
 commit
*
ERROR at line 1:
ORA-00942: table or view does not exist

为什么?

物化视图和同义词依赖关系基于数据字典中的对象 ID,而不是对象名称,因此如果您重建源 table、视图或同义词,您有即使所有内容都具有相同的名称,也无法选择重建物化视图。