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

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

参考


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