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;
/
Хостинг от uCoz