重新编译视图

        当表名、列名、列类型等底层表的信息发生改变的时候,就会使得视图无法使用,其时就需要对视图进行重新的编译。
 
第一步,查找失效的视图。

       可以使用数据字典中的user_objects来查找出失效的视图名,还可以利用user_views来查找出相应视图的代码信息。
基本的代码如下:

----------------查找出失效的视图  
Select object_name,      ---------对象名称  
      object_type,      ---------对象类型   
      status            ---------对象当前状态  
from user_objects        ---------用户对象表  
where object_type= ‘VIEW’    
           and status = ‘INVALID’;  
 
----------------利用上面找出的试图名称,查找出视图的代码  
Select VIEW_NAME,   --------视图名称  
      TEXT         --------视图的代码  
from user_views     --------用户视图表   
where  view_name=’view_name’   


 

第二步,重新编译。

       可以使用以下方式来重新编译视图:

        ALTER  VIEW view_name COMPILE;

        如果视图的结构被改变了(如底层表的列被删除了),则上面的这种方法无法对视图重新编译成功。为此,现在只能把视图删掉,然后重新建立视图。

 

---------建立表和视图  
create table table1  
(  
column1  integer,  
column2  integer  
);  
create view view1 (column3) as  
select column1 as column3 from table1;
 ---------查看修改前的状态
Select object_name,object_type,status   
from user_objects  
where object_type = 'VIEW' ;
and object_name='VIEW1';
 --------修改前的状态为可用
OBJECT_NAME     OBJECT_TYPE    STATUS
------------  ----------  -------------
       VIEW1          VIEW          VALID
----------------修改table1中column1
alter table table1  
modify column1 not null;
 ---------------再次查看修改后视图的状态,发现为“不可用”
Select object_name,object_type,status   
from user_objects  
where object_type = 'VIEW'  
and object_name='VIEW1';
---------------修改后的状态
OBJECT_NAME     OBJECT_TYPE    STATUS
-------------   ---------  -------------
       VIEW1          VIEW          INVALID
---------------对视图进行重新编译
ALTER VIEW view1 COMPILE;
---------------再次查看视图的状态,视图“可用”
Select object_name,object_type,status   
from user_objects  
where object_type = 'VIEW'  
and object_name='VIEW1';
OBJECT_NAME     OBJECT_TYPE    STATUS
-----------   ----------  -----------
       VIEW1          VIEW          VALID
 ---------------如果破坏视图的结构,比如说删除column1,则以上的修复方式无效
alter table table1       
 drop column column1;
 alter view view1 compile;
 --重新编译无效,视图的结构已经改变
--------------删除原来的视图
drop view view1;
 -------------查找出原来的视图语句,根据修改重新建立新的视图
Select VIEW_NAME,TEXT from user_views where  view_name='VIEW1';
 create view view1 as
  select column2  from table1;
 -------------查看视图的状态
Select object_name,object_type,status   
from user_objects  
where object_type = 'VIEW'  
and object_name='VIEW1'
OBJECT_NAME     OBJECT_TYPE    STATUS
------------   -----------  -------------
       VIEW1          VIEW          VALID
 

 

日常管理维护一个oracle数据库服务器的时,经常会碰到修改view,table结构的情况,而且由于oracle view,函数,存储过程等对象的相互关联的关系,经常会由于一个view,table,fun,proc的修改而导致相关的对象失效。而实施的时候,经常只会注意要修改的对象是否修改完成,往往忽略相关对象的失效问题,所以做了一个自动重新编译的脚本程序,目的是定期(10分钟)完成一次对所有对象的检查,如果有失效对象,则对其进行重新编译。 机制是:基于linux的crontab,定期执行下述脚本,对失效的对象,执行alter object_type object_name compile;语句,达到重新编译。 如果扩展该脚本,可以完成对失效的对象进行告警等管理的需要。 该脚本运行于oracle9i,linux 环境下面 #!/bin/sh nowdir=`pwd` #配置文件的生成日期 nowtime=`date '+%Y%m%d'` nowtime_h=`date '+%Y%m%d%H%M'` #脚本执行的目录 dmpdir=/oracle_script/auto_recompile #初始化参数 cd #执行oracle 相关的环境变量, . .bash_profile cd $dmpdir #下面取出失效的对象('TRIGGER','PROCEDURE','FUNCTION','VIEW), #并且去掉系统的对象,只针对用户自己部署的。 #如果有失效对象则完成alter sql语句。 rm -rf param.temp $ORACLE_HOME/bin/sqlplus -SILENT "/ as sysdba" <>$dmpdir/do.log dofilelog="obj_compile"$nowtime_h'.log' $ORACLE_HOME/bin/sqlplus -SILENT "/ as sysdba" <> $dofilelog echo "-------------- Complete export End on `date` -------------" >>$dmpdir/do.log
<think> 我们正在讨论Oracle 19c中批量重新编译视图的方法。根据用户的问题,他想要批量重新编译视图。在Oracle中,视图可能会因为底层表的改变而失效,需要重新编译。 在Oracle中,重新编译视图可以使用"ALTER VIEW ... COMPILE"命令。但是,要批量重新编译,我们需要生成一个脚本,该脚本包含所有需要重新编译视图的ALTER VIEW语句。 步骤: 1. 查询数据字典中所有失效的视图(或者也可以重新编译所有视图,不管是否失效)。 2. 生成相应的ALTER VIEW语句。 注意:重新编译视图通常是为了修复因底层对象变更而导致的视图失效。但是,重新编译视图不会锁定视图,所以在生产环境中可以执行。 我们可以编写一个PL/SQL块来批量执行,也可以生成一个SQL脚本。 方法一:生成SQL脚本并执行 我们可以从DBA_OBJECTS(或ALL_OBJECTS、USER_OBJECTS,根据用户权限和需求)中选择状态为'INVALID'且对象类型为'VIEW'的对象,然后为每个视图生成一条ALTER VIEW COMPILE语句。 示例SQL生成脚本: ```sql SELECT 'ALTER VIEW ' || owner || '.' || object_name || ' COMPILE;' AS command FROM dba_objects WHERE object_type = 'VIEW' AND status = 'INVALID'; ``` 然后执行这些语句。 方法二:使用PL/SQL块 我们可以使用游标遍历所有失效的视图,并动态执行ALTER VIEW语句。 示例PL/SQL块: ```sql BEGIN FOR v IN (SELECT owner, object_name FROM dba_objects WHERE object_type = 'VIEW' AND status = 'INVALID') LOOP EXECUTE IMMEDIATE 'ALTER VIEW ' || v.owner || '.' || v.object_name || ' COMPILE'; END LOOP; END; / ``` 注意:如果视图编译失败,我们需要查看错误信息以修复问题。在批量编译时,我们可以使用DBMS_OUTPUT输出错误,或者使用异常处理继续执行。 增强的PL/SQL块(记录错误并继续): ```sql SET SERVEROUTPUT ON DECLARE v_sql VARCHAR2(200); v_error VARCHAR2(200); BEGIN FOR v IN (SELECT owner, object_name FROM dba_objects WHERE object_type = 'VIEW' AND status = 'INVALID') LOOP v_sql := 'ALTER VIEW ' || v.owner || '.' || v.object_name || ' COMPILE'; BEGIN EXECUTE IMMEDIATE v_sql; DBMS_OUTPUT.PUT_LINE('Compiled: ' || v.owner || '.' || v.object_name); EXCEPTION WHEN OTHERS THEN v_error := SQLERRM; DBMS_OUTPUT.PUT_LINE('Error compiling ' || v.owner || '.' || v.object_name || ': ' || v_error); END; END LOOP; END; / ``` 另外,Oracle还提供了一个内置的包`DBMS_UTILITY.COMPILE_SCHEMA`,它可以编译某个模式下的所有无效对象(包括视图、存储过程等)。但是,它不能只针对视图,而是针对所有对象。如果用户只想重新编译视图,那么上述方法更合适。 使用`DBMS_UTILITY.COMPILE_SCHEMA`编译整个模式下的所有无效对象: ```sql EXEC DBMS_UTILITY.COMPILE_SCHEMA(schema => 'SCHEMA_NAME', compile_all => FALSE); ``` 注意:参数`compile_all`如果为FALSE,则只编译无效对象;如果为TRUE,则编译所有对象(不管是否有效)。但是,这个包会编译所有类型的对象(如过程、函数、包、视图等)。 因此,如果用户只需要重新编译视图,建议使用第一种或第二种方法。 另外,在Oracle 11g及更高版本中,还可以使用`UTL_RECOMP`包来重新编译无效对象,但它也是针对所有类型的无效对象,且主要用于数据库升级后重新编译无效对象。它可以在多个并行进程中进行,但对于只编译视图来说,可能过于重量级。 结论: 对于批量重新编译视图,建议使用动态生成ALTER VIEW语句并执行的方法。 注意事项: 1. 执行用户需要有ALTER ANY VIEW的权限(如果是其他用户的视图)或者相应视图的ALTER权限。 2. 重新编译视图不会影响视图的使用(即不会阻止其他会话查询视图),但在编译的瞬间会有一个短暂的锁(数据字典锁),通常非常快。 3. 如果视图编译失败,视图状态将保持为INVALID,需要手动修复。 因此,我们可以根据上述方法之一来批量重新编译视图。 生成相关问题: 1. 如何检查Oracle数据库中所有失效的视图? 2. 重新编译视图时遇到错误怎么办? 3. 除了重新编译视图,还有哪些方法可以处理失效的数据库对象? 4. 使用DBMS_UTILITY.COMPILE_SCHEMA与逐个编译视图有什么区别? </think> 在Oracle 19c中批量重新编译视图,可通过以下方法实现: ### 方法1:使用动态SQL批量编译失效视图 ```sql BEGIN FOR rec IN ( SELECT owner, object_name FROM dba_objects WHERE object_type = 'VIEW' AND status = 'INVALID' -- 仅编译失效视图 ) LOOP EXECUTE IMMEDIATE 'ALTER VIEW ' || rec.owner || '.' || rec.object_name || ' COMPILE'; END LOOP; END; / ``` **说明**: 此PL/SQL块自动检测所有失效视图并逐条执行`ALTER VIEW ... COMPILE`命令。需用户具有`ALTER ANY VIEW`权限[^1]。 --- ### 方法2:使用DBMS_UTILITY编译整个模式 ```sql EXEC DBMS_UTILITY.COMPILE_SCHEMA(schema => 'YOUR_SCHEMA', compile_all => FALSE); ``` **参数说明**: - `schema`:目标模式名 - `compile_all`: - `FALSE`:仅编译失效对象(推荐) - `TRUE`:强制编译所有对象 --- ### 方法3:查询失效视图并手动执行(推荐审计场景) ```sql SELECT 'ALTER VIEW ' || owner || '.' || object_name || ' COMPILE;' AS compile_cmd FROM dba_objects WHERE status = 'INVALID' AND object_type = 'VIEW' AND owner = 'YOUR_SCHEMA'; -- 指定模式 ``` **操作流程**: 1. 运行上述SQL生成编译命令 2. 复制输出结果手动执行 --- ### 关键注意事项 1. **权限要求**: - 执行用户需具备`ALTER ANY VIEW`权限 - 跨模式操作需`SYSDBA`或对象所有者权限 2. **依赖关系处理**: - 若视图依赖的基础表结构变更,需优先修复底层对象 - 编译失败时检查`USER_ERRORS`视图: ```sql SELECT * FROM USER_ERRORS WHERE TYPE = 'VIEW'; ``` 3. **性能影响**: - 大型视图编译可能消耗较多SGA内存 - 建议在业务低峰期操作,避免`library cache lock`等待事件[^1] --- ### 相关问题 1. 如何检测Oracle数据库中所有失效对象? 2. 视图编译失败后如何快速定位错误原因? 3. 除了重新编译,还有哪些方法解决Oracle对象失效问题? 4. DBMS_UTILITY.COMPILE_SCHEMA与手动编译有何性能差异? [^1]: Oracle等待事件及解决方案指南
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值