Create Or Replace FUNCTION COMPILE_INVALID (list_err_obj OUT VARCHAR2 ) RETURN NUMBER
/* Функция ищет 'invalid' объекты и переводит их в нормальное состояние,
если это возможно. Если остаются 'invalid' объекты, делаются ещё попытки
их откомпилировать до тех пор, пока их кол-во уменьшается.
На выход выдаёт список и количество оставшихся после
перекомпиляций 'invalid' объектов */
IS
CURSOR obj_cur(obt all_objects.object_type%TYPE) IS
SELECT *
FROM all_objects
WHERE owner='ubc' AND
object_type=obt AND status<>'VALID';
CURSOR obj_cur_all IS
SELECT *
FROM all_objects
WHERE owner='ubc' AND
status<>'VALID';
obj_row obj_cur%ROWTYPE;
v_cursor number;
cnt_obj number;
delt number:=0;
n number:=1;
BEGIN
LOOP -- цикл проходов по инвалидным объектам
SELECT COUNT (*) INTO cnt_obj --проверка на наличие неисправных объектов
FROM all_objects WHERE owner='ubc' AND status<>'VALID';
IF cnt_obj>0 THEN
DBMS_OUTPUT.PUT_LINE('Проход '||n);
n:=n+1;
DBMS_OUTPUT.PUT_LINE('Список ''INVALID'' объектов:');
DBMS_OUTPUT.PUT_LINE('----------------------------');
v_cursor:=DBMS_SQL.open_cursor;
FOR obj_row IN obj_cur('TRIGGER') LOOP
begin
DBMS_SQL.parse(v_cursor,'alter trigger '||obj_row.object_name||' compile',dbms_sql.v7);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
exception when others then
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
end;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(v_cursor);
v_cursor:=DBMS_SQL.open_cursor;
FOR obj_row IN obj_cur('VIEW') LOOP
begin
DBMS_SQL.parse(v_cursor,'ALTER VIEW '||obj_row.object_name||' COMPILE',dbms_sql.v7);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
exception when others then
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
end;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(v_cursor);
FOR obj_row IN obj_cur('PROCEDURE') LOOP
BEGIN
DBMS_DDL.ALTER_COMPILE ('PROCEDURE', 'ubc', obj_row.object_name);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
EXCEPTION WHEN others THEN
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
END;
END LOOP;
FOR obj_row IN obj_cur('FUNCTION') LOOP
BEGIN
DBMS_DDL.ALTER_COMPILE ('FUNCTION', 'ubc', obj_row.object_name);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
EXCEPTION WHEN others THEN
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
END;
END LOOP;
FOR obj_row IN obj_cur('PACKAGE BODY') LOOP
BEGIN
DBMS_DDL.ALTER_COMPILE ('PACKAGE BODY', 'ubc', obj_row.object_name);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
EXCEPTION WHEN others THEN
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
end;
END LOOP;
FOR obj_row IN obj_cur('PACKAGE') LOOP
begin
DBMS_DDL.ALTER_COMPILE ('PACKAGE', 'ubc', obj_row.object_name);
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
EXCEPTION WHEN others THEN
DBMS_OUTPUT.PUT_LINE('ups..except on '||obj_row.object_name);
END;
END LOOP;
-- проверка на наличие неудачно откомпилированных объектов
list_err_obj:='';
SELECT COUNT (*) INTO cnt_obj
FROM all_objects WHERE owner='ubc' AND status<>'VALID';
IF cnt_obj>0 THEN
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('Осталось '||cnt_obj||' неисправных объектов:');
DBMS_OUTPUT.PUT_LINE('--------------------------------');
FOR obj_row IN obj_cur_all LOOP
DBMS_OUTPUT.PUT_LINE(obj_row.object_type||' '|| obj_row.object_name);
list_err_obj:=list_err_obj||', '||obj_row.object_type||' '|| obj_row.object_name ;
END LOOP;
ELSE DBMS_OUTPUT.PUT_LINE('Все объекты теперь в исправном состоянии.');
END IF;
ELSE DBMS_OUTPUT.PUT_LINE('В базе нет "инвалидных" объектов.');
END IF;
delt:=cnt_obj-delt; --если прогресса в перекомпиляции нет, то на выход
IF delt=0 THEN EXIT;
END IF;
END LOOP; --проходов по инвалидным объектам
RETURN cnt_obj; --количество оставшихся 'INVALID' объектов.
END;
/