Oracle程序立即执行

时间:2014-02-04 06:20:35

标签: sql oracle plsql

我在SYS下有一个存储过程,它使用EXECUTE IMMEDIATE命令来执行alter object compile。但我收到以下错误。

CREATE OR REPLACE PROCEDURE comp_inv
is   
   CURSOR empCursor IS 
      SELECT object_type, 
             owner,object_name 
        from dba_objects
       where status = 'INVALID' 
         and object_type in ('PACKAGE','FUNCTION','PROCEDURE');    
BEGIN
   FOR i_rec IN empCursor LOOP       
      execute immediate 'alter ' ||i_rec.object_type|| ' ' || 
                         i_rec.owner || '.' || i_rec.object_name || ' compile';  
   END LOOP;
END;
/
SQL> exec comp_inv;
ERROR:
ORA-24344: success with compilation error
ORA-06512: at "SYS.COMP_INV", line 8
ORA-06512: at line 1


Warning: PL/SQL compilation errors.

SQL> show errors procedure comp_inv;
No errors.

4 个答案:

答案 0 :(得分:3)

您可以使用标准Oracle包DBMS_UTILITY及其过程COMPILE_SCHEMA(),它为您提供了重新编译无效对象的标准方法。值得使用它有很多原因,特别是它允许你保持编译设置。

答案 1 :(得分:3)

在您的情况下,错误只是意味着某些架构对象由于某种原因无法重新编译 - 过程成功执行,但您尝试重新编译的某些对象无法重新编译。例如:

create table t1(col1 number);

create or replace procedure p2(p_in in number) is
  l_res number;
begin
  select count(1)
    into l_res
    from t1;
end;

确定那里是否存在“无效”:

column object_type format a10;
column object_name format a10;
column status      fromat a10;

select object_type
     , object_name 
     , status
  from dba_objects
 where status = 'INVALID' 
   and object_type in ('PACKAGE','FUNCTION','PROCEDURE'); 

 no rows selected

无效P2程序:

alter table t1 add (col2 number);

column object_type format a10;
column object_name format a10;
column status      fromat a10;

select object_type
     , object_name 
     , status
  from dba_objects
 where status = 'INVALID' 
   and object_type in ('PACKAGE','FUNCTION','PROCEDURE');

OBJECT_TYP OBJECT_NAM STATUS
---------- ---------- -------
PROCEDURE  P2         INVALID

重新编译:

exec comp_inv

anonymous block completed

重新编译成功:

column object_type format a10;
column object_name format a10;
column status      fromat a10;

select object_type
     , object_name 
     , status
  from dba_objects
 where status = 'INVALID' 
   and object_type in ('PACKAGE','FUNCTION','PROCEDURE');

 no rows selected

使我们的P2程序无效,因此无法编译:

create or replace procedure p2(p_in in number) is
  l_res number;
begin
  invalid_operator;
end;
/

PROCEDURE P2 compiled
Errors: check compiler log

检查无效对象:

column object_type format a10;
column object_name format a10;
column status      fromat a10;

select object_type
     , object_name 
     , status
  from dba_objects
 where status = 'INVALID' 
   and object_type in ('PACKAGE','FUNCTION','PROCEDURE');

OBJECT_TYP OBJECT_NAM STATUS
---------- ---------- -------
PROCEDURE  P2         INVALID

尝试重新编译该过程:

exec comp_inv

ORA-24344: success with compilation error
ORA-06512: at "SYS.COMP_INV", line 11
ORA-06512: at line 1
24344. 00000 -  "success with compilation error"

正如@OracleUser已经说过的那样,检查一个*_errors数据字典视图,看看其中是否有内容。它将为您提供消除威胁所需的信息

column owner format a10;
column name  format a10;
column type  format a10;
column text  format a60;

select owner
     , name
     , type
     , text
  from dba_errors

OWNER      NAME       TYPE      TEXT  
------ ---------- ------------------------------------------------------------
NK         P2         PROCEDURE  PLS-00201: identifier 
                                             'INVALID_OPERATOR' must be declared 
NK         P2         PROCEDURE  PL/SQL: Statement ignored   

其次,正如@Frank Schmitt在他对你的问题的评论中所指出的那样,永远不会在SYS模式中创建任何类型的用户对象。如果您需要在某处存储某些管理存储过程或其他对象,请为其授予不同的用户权限,并为其授予适当的权限和角色,或者作为最后的手段使用SYSTEM(也不建议使用)架构。

答案 2 :(得分:2)

CREATE OR REPLACE PROCEDURE comp_inv
is   
   CURSOR empCursor IS 
      SELECT object_type, 
             owner,object_name 
        from dba_objects
       where status = 'INVALID' 
         and object_type in ('PACKAGE','FUNCTION','PROCEDURE');    
BEGIN
   FOR i_rec IN empCursor LOOP
      BEGIN
        execute immediate 'alter ' ||i_rec.object_type|| ' ' || 
                         i_rec.owner || '.' || i_rec.object_name || ' compile';
      EXCEPTION
      WHEN OTHERS THEN
         FOR I IN (select * from DBA_ERRORS where NAME = i_rec.object_name and owner = i_rec.owner AND type = i_rec.object_type)
         LOOP
                DBMS_OUPT.PUT_LINE(I.line || ' ' || I.text);
         END LOOP;
      END;

   END LOOP;
END;
/

答案 3 :(得分:0)

这可能就是你所需要的。

    exec dbms_utility.compile_schema('SCOTT');

当然你需要适当的权利才能执行