2011-08-23 73 views
0
/* Formatted on 23/08/2011 12:42:42 (QP5 v5.163.1008.3004) */ 
CREATE OR REPLACE PROCEDURE COUNT_N_COMPILE AS  

ERR_MSG  VARCHAR2(100);  
COUNT_ERRORS NUMBER := 0;  
A    NUMBER := 0; 
B    NUMBER := 0; 
C    NUMBER := 0;  
D    NUMBER := 0; 

    CURSOR CUR_LOOP IS 
     SELECT OWNER, OBJECT_NAME, OBJECT_TYPE 
     FROM DBA_OBJECTS 
     WHERE OBJECT_TYPE IN 
       ('PACKAGE', 
        'PACKAGE BODY', 
        'VIEW', 
        'INDEX', 
        'PROCEDURE', 
        'FUNCTION', 
        'MATERIALIZED VIEW', 
        'SYNONYM') 
       AND OBJECT_NAME NOT IN ('%$%') 
       AND STATUS != 'VALID'; 
BEGIN 
<GENERIC_CODE.DROPIFEXISTS (USER, 'COUNT_N_COMPILE_TABLE'); --drops if the table exists 

    EXECUTE IMMEDIATE 'CREATE TABLE COUNT_N_COMPILE_TABLE 
        (
        OWNER VARCHAR2(300), 
        OBJECT_NAME VARCHAR2(300), 
        ERROR_STORED VARCHAR2(3000) 
        ) 
        LOGGING 
        NOCOMPRESS 
        NOCACHE 
        NOPARALLEL 
        MONITORING'; 

    FOR CUR_REC IN CUR_LOOP LOOP 
     BEGIN 
      CASE 
      WHEN CUR_REC.OBJECT_TYPE IN 
        ('VIEW', 'INDEX', 'PROCEDURE', 'FUNCTION') 
      THEN 
       A := A + 1; 

       EXECUTE IMMEDIATE 
         'ALTER ' 
        || CUR_REC.OBJECT_TYPE 
        || ' "' 
        || CUR_REC.OWNER 
        || '"."' 
        || CUR_REC.OBJECT_NAME 
        || '" COMPILE'; 
      WHEN CUR_REC.OBJECT_TYPE = 'MATERIALIZED VIEW' 
      THEN 
       B := B + 1; 

       EXECUTE IMMEDIATE 
         'ALTER ' 
        || CUR_REC.OBJECT_TYPE 
        || ' "' 
        || CUR_REC.OWNER 
        || '"."' 
        || CUR_REC.OBJECT_NAME 
        || '" COMPILE'; 
      WHEN CUR_REC.OBJECT_TYPE = 'SYNONYM' 
      THEN 
       C := C + 1; 

       EXECUTE IMMEDIATE 
         'ALTER ' 
        || CUR_REC.OBJECT_TYPE 
        || ' "' 
        || CUR_REC.OWNER 
        || '"."' 
        || CUR_REC.OBJECT_NAME 
        || '" COMPILE'; 
      WHEN CUR_REC.OBJECT_TYPE = 'PACKAGE' 
      THEN 
       D := D + 1; 

       EXECUTE IMMEDIATE 
         'ALTER ' 
        || CUR_REC.OBJECT_TYPE 
        || ' "' 
        || CUR_REC.OWNER 
        || '"."' 
        || CUR_REC.OBJECT_NAME 
        || '" COMPILE'; 
      ELSE 
       D := D + 1; 

       EXECUTE IMMEDIATE 
         'ALTER PACKAGE "' 
        || CUR_REC.OWNER 
        || '"."' 
        || CUR_REC.OBJECT_NAME 
        || '" COMPILE BODY'; 
      END CASE; 
     EXCEPTION 
      WHEN OTHERS 
      THEN 
      ERR_MSG := SUBSTR (CUR_REC.OBJECT_TYPE || ' ' || SQLERRM, 1, 100); 
      DBMS_OUTPUT.PUT_LINE (ERR_MSG); 
      COUNT_ERRORS := COUNT_ERRORS + 1; 

      INSERT 
       INTO COUNT_N_COMPILE_TABLE (OWNER, OBJECT_NAME, ERROR_STORED) 
      VALUES (CUR_REC.OWNER, CUR_REC.OBJECT_NAME, ERR_MSG); 
     END;  
     END LOOP; 

    DBMS_OUTPUT.PUT_LINE ('PROC, FUNCTION, INDEX, VIEWS ' || A); 
    DBMS_OUTPUT.PUT_LINE ('PACKAGES ' || D);  
    DBMS_OUTPUT.PUT_LINE ('MATERIALIZED VIEW ' || B);  
    DBMS_OUTPUT.PUT_LINE ('SYNONYMS ' || C); 
    DBMS_OUTPUT.PUT_LINE (' TOTAL NUMBER OF ERRORS ' || COUNT_ERRORS);  
    COMMIT; 
END; 

/編譯甲骨文invalid_objects .....想如果這是正確的做法

+1

我想補充一個ORDER BY等等該軟件包是在機構之前編譯的。 –

+0

'BEGIN FOR EACH_ROW IN CUR_REC LOOP BEGIN DBMS_UTILITY.compile_schema(''|| EACH_ROW.OWNER ||''); EXCEPTION 當其他人 THEN ERR_MSG:= SUBSTR(EACH_ROW.OBJECT_TYPE ||''|| SQLERRM,1,100); DBMS_OUTPUT.PUT_LINE(ERR_MSG); COUNT_ERRORS:= COUNT_ERRORS + 1; (所有者,OBJECT_NAME,ERROR_STORED) VALUES(EACH_ROW.OWNER,EACH_ROW.OBJECT_NAME,ERR_MSG); END; END LOOP; END'; – Imran

+1

你可以在這裏找到不同的技術:http://www.oracle-base.com/articles/misc/RecompilingInvalidSchemaObjects.php請注意,類似於你的代碼的「自定義腳本」是不完整的,並且需要幾個對象類型被添加到它。 –

回答

4

你可以使用:

exec dbms_utility.compile_schema('YOURSCHEMAHERE') 

還看到:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:637156098168

+1

如果一個未編譯的對象被調用,調用者將會得到一個異常,Oracle將編譯這個對象。許多程序不會優雅地處理這些異常,所以在運行任何DDL語句後重新編譯任何無效對象被認爲是一種好的做法。 –

+0

好點我會刪除那 –

+1

+1;但是,如果您有架構間依賴關係,那麼utl_recomp包或utlprp腳本可能是更好的選擇。查看上面@Klas提供的鏈接。 – DCookie