在查询dblink关联的一个视图时报错如图,经查询改dblink是建在DG库中。
该视图在主节点是可以查询的,后来经过分析了解到,dba对视图基表的字段进行了修改,进而引起备节点出现这个报错。原因是在备节点时,内存里信息没有更新,后来进行查询时,发现与基表有差异,需要进行重新编译,但是dg库是read only的,所以编译报错;
解决办法:
方法1:在主库执行手动compile,这个动作会同步到从库执行;
SQL> alter view 视图名称 compile;
View altered.
方法2:直接在主库查询下这个视图就可以自动触发视图的自动编译,进而同步到从库执行;
SQL>select * from 视图名称;
拓展:可以通过如下存储过程,批量编译无效的视图
create or replace procedure compile_invalid_views(
p_owner varchar2 -- 所有者名称,即 SCHEMA
) as
--编译某个用户下的无效视图
str_sql varchar2(200);
begin
for invalid_views in (select object_name from all_objects
where status = 'INVALID' and object_type = 'VIEW' and owner=upper(p_owner))
loop
str_sql := 'alter view '||p_owner||'.' ||invalid_views.object_name || ' compile';
begin
execute immediate str_sql;
exception
--When Others Then Null;
when OTHERS Then
dbms_output.put_line(sqlerrm);
end;
end loop;
end;
执行方式:
例如执行编译试图的存储过程,如下所示编译sysadm下面的所有无效的试图
SQL> exec compile_invalid_views('sysadm');
PL/SQL procedure successfully completed.
综上所述:Oracle dg做读写分离的时候,使用视图需要注意,当基表发生变化的时候,需要重新编译下对应的试图,或者定时从新编译主库的试图来避免这个问题,如果没有使用dg库读取,那么不会有这个问题