Иногда после после проведения изменений в одном пакете Oracle, остальные могут встать в состояние Invalid. Связано это с тем, что в базе хранится timestamp для каждого пакета и его состояния на тот момент. Со сменой timestamp (в пакете были произведены изменения), все связующие пакеты необходимо перекомпилировать. В принципе можно этого не делать, но при первом запуске процедуры любого их этих пакетов выскочит сообщение об ошибке. После этого база сама поменяет статусы пакетов и со второго раза все будет работать. Чтобы избежать таких проблем при первом запуске, можно использовать небольшой скрипт, который пробегает по инвалидным объектам и компилирует их заново:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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; |