こちらの記事は2015年08月31日にQiitaに投稿したものを移植したものとなります。

Qiitaからの移植に当たって内容の精査は行っていません。
従って、記事は当時の私の知識や当時の技術そのままです。

質問について


※ここの部分はQiitaに記述していたものではなく今回追記してます。

こちらの記事に対して「DECODEでVIEWをFUNCTIONとしてコンパイルしてませんか?」という質問をQiitaに掲載していた時に頂いていますが、既に筆者がORACLEの記憶がないため申し訳ありませんが回答できません。

何卒ご容赦ください。

UTL_RECOMPパッケージを使う場合


ORACLEには無効なパッケージをリコンパイルしてくれる「UTL_RECOMP」パッケージがあります。このパッケージの「RECOMP_SERIAL」プロシージャを実行するのが一番手っ取り早いです。

1
--※スキーマ名を省略した場合、全てのオブジェクトに対してリコンパイルを行う。
2
CALL UTL_RECOMP.RECOMP_SERIAL('スキーマ名');

実行にはいくらか注意点があります。

  • AS SYSDBAで接続する必要がある。
  • SQLPLUSから実行する。
  • 10g以降。(今時9i以前はありえないと思われる)

UTL_RECOMPパッケージを使用しない場合


何らかの事情で「UTL_RECOMP」を使用できない場合、例えば・・・

  • SYSDBA権限で接続しようにもパスワードがわからない。
  • バッチファイルで自動でリコンパイルをかけたいが、SYSユーザのパスワードを書きたくない。

…等

今回、後者の事情で無効オブジェクト一覧を取得して「ALTER ***** COMPILE」を実行するPLSQLを書いてみました。リコンパイルを行いたいユーザで接続しているのが前提です。

1
DECLARE
2
  --無効オブジェクトを取得
3
  CURSOR RECONPILE_CUR IS
4
          (SELECT 
5
          'ALTER ' || DECODE(OBJECT_TYPE,'PACKAGE BODY','PACKAGE','VIEW','FUNCTION',OBJECT_TYPE) || ' ' || OBJECT_NAME || ' COMPILE' AS ALTER_SQL
6
          FROM	USER_OBJECTS
7
          WHERE	STATUS = 'INVALID'
8
          );
9
BEGIN
10
  --順に実行
11
  FOR C1 IN RECONPILE_CUR LOOP
12
    DECLARE
13
    BEGIN
14
      EXECUTE IMMEDIATE C1.ALTER_SQL;
15
      DBMS_OUTPUT.PUT_LINE('DONE  : ' || C1.ALTER_SQL);
16
    EXCEPTION WHEN OTHERS THEN
17
      DBMS_OUTPUT.PUT_LINE('ERROR : ' || C1.ALTER_SQL);
18
    END;
19
  END LOOP;
20
END;

カーソルに無効オブジェクト一覧をもとに作成した「ALTER ***** COMPILE」文を格納します。後は「EXECUTE IMMEDIATE」で順次実行します。

参考


http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19245-02/u_recomp.htm