Компиляция инвалидных пакетов 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;