Как запустить UTL_RECOMP.RECOMP_PARALLEL из процедуры?

У меня простой вопрос: можно ли запустить UTL_RECOMP.RECOMP_PARALLEL из процедуры? У меня есть пакет с процедурой, которая должна перекомпилировать все недопустимые объекты. Это выглядит так:

    PROCEDURE Compile ()
    IS
    BEGIN
        EXECUTE IMMEDIATE ('BEGIN SYS.UTL_RECOMP.RECOMP_PARALLEL(4,); END;');
        EXCEPTION
            WHEN OTHERS
            THEN
            DBMS_OUTPUT.PUT_LINE(SQLERRM);

    END; 

Однако я всегда получаю сообщение об ошибке PLS-00201: должен быть объявлен идентификатор UTL_RECOMP.RECOMP_PARALLEL. Я вошел в систему как пользователь sys/sysdba. Это не проблема.

Любые идеи, как заставить это работать?

Спасибо!


person digestBen    schedule 09.04.2020    source источник
comment
Из документации - Этот пакет должен запускаться с помощью SQL*PLUS.   -  person OldProgrammer    schedule 10.04.2020


Ответы (2)


На самом деле это работает, если процедура принадлежит SYS, и вы предоставляете привилегию EXECUTE другому пользователю (документ говорит: «Вы должны быть подключены как SYSDBA для запуска этого сценария»).

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> show user;
USER is "SYS"
SQL> --
SQL> CREATE OR REPLACE PROCEDURE Compile
  2  IS
  3  BEGIN
  4   SYS.UTL_RECOMP.RECOMP_PARALLEL(4);
  5  END;
  6  /

Procedure created.

SQL> --
SQL> grant execute on compile to c##test;

Grant succeeded.

SQL> --
SQL> connect c##test/c##test
Connected.
SQL> show user
USER is "C##TEST"
SQL> --
SQL> drop table t purge;

Table dropped.

SQL> create table t(x int);

Table created.

SQL> create or replace procedure p
  2  is
  3  v int;
  4  begin
  5   select x into v from t;
  6  end;
  7  /

Procedure created.

SQL> --
SQL> show errors
No errors.
SQL> --
SQL> drop table t;

Table dropped.

SQL> --
SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_name='P';

OBJECT_NAM OBJECT_TYP STATUS
---------- ---------- ----------
P      PROCEDURE  INVALID

SQL> --
SQL> create table t(x int);

Table created.

SQL> --
SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_name='P';

OBJECT_NAM OBJECT_TYP STATUS
---------- ---------- ----------
P      PROCEDURE  INVALID

SQL> --
SQL> exec sys.compile;

PL/SQL procedure successfully completed.

SQL> --
SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_name='P';

OBJECT_NAM OBJECT_TYP STATUS
---------- ---------- ----------
P      PROCEDURE  VALID

SQL> --

Такого рода процедуры должны выполняться только SYS (например, utlrp.sql) — так что это только для DBA — как задокументировано, чтобы избежать неожиданного поведения.

person pifor    schedule 10.04.2020

Вы можете использовать его в хранимой процедуре:

SQL> set serveroutput on
SQL> --
SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

SQL> show user;
USER is "SYS"
SQL> --
SQL> CREATE OR REPLACE PROCEDURE Compile
  2  IS
  3  BEGIN
  4   UTL_RECOMP.RECOMP_PARALLEL(4);
  5   EXCEPTION
  6     WHEN OTHERS
  7     THEN
  8     DBMS_OUTPUT.PUT_LINE(SQLERRM);
  9  END;
 10  /

Procedure created.

SQL> --
SQL> show errors
No errors.
SQL> --
SQL> set timing on
SQL> exec compile;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.31
SQL> --
SQL> exit
person pifor    schedule 10.04.2020
comment
Это не работает для меня. Точно такая же Ошибка. Но, возможно, это связано с процедурой, которая находится внутри пакета. Извините, я забыл это сказать... Сама процедура находится внутри пакета, который находится не в схеме SYS, а в другой. Но я подключаюсь как sys/sysdba - person digestBen; 10.04.2020
comment
Итак, я нашел причину этой проблемы. Мне нужно предоставить права другой схеме, содержащей пакет, для выполнения этого sys.Utl_recomp. ПРЕДОСТАВЬТЕ ВЫПОЛНЕНИЕ SYS.UTL_RECOMP ДЛЯ ВАШЕЙ_СХЕМЫ - person digestBen; 10.04.2020
comment
Я только что проверил, что это действительно не работает. У меня нет ошибок, но id ничего не делает. Если я просто поставлю SYS.UTL_RECOMP.RECOMP_PARALLEL(4) и выполню эту процедуру, ничего не произойдет. Объекты не компилируются. Любые другие идеи или подходы? - person digestBen; 10.04.2020