ablog

不器用で落着きのない技術者のメモ

無効オブジェクトをコンパイルする方法

Oracle Database で無効な PL/SQL オブジェクトをコンパイルし、無効なインデックスを再構築する手順。
まだちゃんと検証してないけど、とりあえずメモっておく。

conn / as sysdba
--無効な PL/SQL オブジェクトをコンパイルする
EXECUTE UTL_RECOMP.RECOMP_SERIAL('SCOTT');
--無効なインデックスを再構築する
@rebuild_unusable_indexes.sql
Enter value for owner_name: SCOTT
--無効な PL/SQL オブジェクトがないことを確認する
select object_name,status from dba_objects where owner = 'SCOTT' and status <> 'VALID';
--無効なインデックスがないことを確認する
SQL> select i.index_name, i.status, p.partition_name, p.status, s.subpartition_name, s.status
	from dba_indexes i 
		left outer join dba_ind_partitions p
			on i.index_name = p.index_name
				left outer join dba_ind_subpartitions s
					on i.index_name = s.index_name
	where i.owner in ('SCOTT')
		and i.owner = p.index_owner
		and i.status <> 'VALID'
		and p.status <> 'USABLE'
		and s.status <> 'USABLE';


追記:
簡単に検証してみた。

--無効オブジェクトを作成する
SQL> conn scott/tiger
SQL> select object_name from user_objects;

no rows selected

SQL> create table t1 as
select level as c1, 'x' as c2
from dual
connect by level <= 1000;

SQL> create table t2 as
select level as c1, 'x' as c2
from dual
connect by level <= 1000;

SQL> create view v1 as 
select 't1' table_name, count(1) row_count from t1
union
select 't2' table_name, count(1) row_count from t2;

SQL> create index t1_n1 on t1(c1);

SQL> create or replace function f1(p1 number)
return varchar2 as
v1 varchar2(10);
begin
	select c1 into v1 from t2;
	return v1;
end;
/

SQL> alter table t1 move tablespace users;
SQL> drop table t2;
SQL> create table t2 as
select level as c1, 'x' as c2
from dual
connect by level <= 1000;

SQL> col object_name for a30
SQL> select object_name, object_type, status from user_objects where status <> 'VALID';

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
F1                             FUNCTION            INVALID
V1                             VIEW                INVALID

SQL> col index_name for a30
SQL> select index_name,status from user_indexes where status <> 'VALID';

INDEX_NAME                     STATUS
------------------------------ --------
T1_N1                          UNUSABLE


--無効オブジェクトを有効化する。
SQL> conn / as sysdba

SQL> EXECUTE UTL_RECOMP.RECOMP_SERIAL('SCOTT');

PL/SQL procedure successfully completed.

--無効なインデックスを再構築する。
SQL> @rebuild_unusable_indexes.sql
Enter value for owner_name: SCOTT

--無効な PL/SQL オブジェクトがないことを確認する
SQL> conn scott/tiger
SQL> col object_name for a30
SQL> select object_name, object_type, status from user_objects where status <> 'VALID';

no rows selected

--無効なインデックスがないことを確認する
SQL> col index_name for a30
SQL> select index_name,status from user_indexes where status <> 'VALID';

no rows selected