Компиляция инвалидных пакетов Oracle

Компиляция инвалидных пакетов Oracle

Иногда после после проведения изменений в одном пакете Oracle, остальные могут встать в состояние Invalid. Связано это с тем, что в базе хранится timestamp для каждого пакета и его состояния на тот момент. Со сменой timestamp (в пакете были произведены изменения), все связующие пакеты необходимо перекомпилировать.

В принципе можно этого не делать, но при первом запуске процедуры любого их этих пакетов выскочит сообщение об ошибке. После этого база сама поменяет статусы пакетов и со второго раза все будет работать. Чтобы избежать таких проблем при первом запуске, можно использовать небольшой скрипт, который пробегает по инвалидным объектам и компилирует их заново:

BEGIN
    FOR CUR_REC IN (SELECT OWNER
                                                    ,OBJECT_NAME
                                                    ,OBJECT_TYPE
                                                    ,DECODE(OBJECT_TYPE,
                                                                      'PACKAGE', 1,
                                                                      'PACKAGE BODY', 2,
                                                                       2) AS RECOMPILE_ORDER
                                         FROM ALL_OBJECTS
                                       WHERE OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY')
                                            AND OWNER = USER AND STATUS != 'VALID')
    LOOP
        BEGIN
           IF CUR_REC.OBJECT_TYPE = 'PACKAGE' THEN
              EXECUTE IMMEDIATE 'ALTER ' || CUR_REC.OBJECT_TYPE || ' "' || CUR_REC.OWNER || '"."' || CUR_REC.OBJECT_NAME || '" COMPILE';
           ELSE
              EXECUTE IMMEDIATE 'ALTER PACKAGE "' || CUR_REC.OWNER || '"."' || CUR_REC.OBJECT_NAME || '" COMPILE BODY';
           END IF;
        EXCEPTION WHEN OTHERS THEN
             DBMS_OUTPUT.PUT_LINE(CUR_REC.OBJECT_TYPE || ' ' || CUR_REC.OWNER || '.' || CUR_REC.OBJECT_NAME || ' compiled with errors');
        END;
     END LOOP;
END;