2014-02-04 3 views
2

У меня есть хранимая процедура в SYS, которая использует команду EXECUTE IMMEDIATE для выполнения alter object compile. Но я получаю следующую ошибку.Процедура Oracle немедленно выполнить

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. 
+1

выберите * из USER_ERRORS где NAME = i_rec.object_name и типа = i_rec.object_type; Вы можете использовать это в своем коде, поэтому вы сразу обнаруживаете ошибки. Поскольку это выполняется через proc, я думаю, что ошибки sho могут не отображать их. –

+5

Вы должны * НИКОГДА НИКОГДА не создавать объекты под учетной записью SYS. Если вы допустили ошибку, скорее всего, ваша система станет недоступной, и поддержка Oracle, вероятно, откажется помочь вам, если вы внесли изменения в схему SYS. –

ответ

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

Вы можете использовать стандартный пакет Oracle DBMS_UTILITY и это процедура COMPILE_SCHEMA(), которая дает вам стандартный способ перекомпиляции недействительные объекты. Стоит использовать его по многим причинам, в частности, он позволяет сохранять параметры компиляции.

+0

@ Николас Краснов Я знаю все это выше. Но все, что я вижу в исходном посте, - это попытка перекомпиляции с использованием пользовательской процедуры, созданной в схеме SYS, - не лучшим образом, как я думаю. –

+0

Поверьте мне, если вы используете эту функцию, все ваши сохраненные программы будут перекомпилированы, а иногда они вызовут проблемы (т.е. сбой системы). S используйте это тщательно и своевременно! – hmmftg

+0

@hmmftg Да, полная перекомпиляция действительно может привести к сбою системы, поэтому Oracle предоставляет параметр compile_all для управления им (к сожалению, он имеет значение «true» по умолчанию, и вы на 100% жестко - это ловушка). –

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; 

Определить, если есть что-то "INVALID" есть:

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 

Invalidate 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 

Recompilatio п пошел успешно:

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 (и это тоже не рекомендуется).

0

это может быть то, что вам нужно.

exec dbms_utility.compile_schema('SCOTT'); 

с курсом вам необходимы соответствующие права для выполнения, что

+0

На самом деле вам лучше подключиться как пользователь Sys! – hmmftg

Смежные вопросы