本文摘自《oracle 索引技术》 第37页和第38页
检查外键列是否是索引列的语句之一:
select distinct
a.owner owner,
a.constraint_name cons_name,
a.table_name tab_name,
b.column_name cons_column,
nvl(c.column_name,'***Check index***') ind_column
from dba_constraints a,
dba_cons_columns b,
dba_ind_columns c
where constraint_type='R'
and a.owner=upper('&user_name')
and a.owner=b.owner
and a.constraint_name=b.constraint_name
and b.column_name=c.column_name(+)
and b.table_name=c.table_name(+)
and b.position=c.column_position(+)
order by tab_name, ind_column;
以上查询语句并不能在所有情况下都正确的报告出未索引的外键。
比如,在多列外键的情况下,以不同于索引列的书序定义约束也不要紧,只要索引列在该索引中位于前面即可。
检查外键列是否是索引列的语句之二:--使用listagg分析函数(该函数是11g新特性)
select
case when ind.index_name is not null then
case when ind.index_type in ('BITMAP') then
'** Bitmp idx **'
else
'indexed'
end
else
'** Check idx **'
end checker,
ind.index_type,cons.owner,cons.table_name, ind.index_name,cons.constraint_name,cons.cols
from
(
select c.owner,c.table_name,c.constraint_name,listagg(cc.column_name,',') within group (order by cc.column_name) cols
from dba_constraints c, dba_cons_columns cc
where c.owner=cc.owner
and c.owner=upper('&schema')
and c.constraint_name=cc.constraint_name
and c.constraint_type='R'
group by c.owner,c.table_name,c.constraint_name
) cons
left outer join
(
select table_owner,table_name,index_name,index_type,cbr,listagg(column_name,',') within group (order by column_name) cols
from
(select ic.table_owner,ic.table_name,ic.index_name,ic.column_name,
ic.column_position,i.index_type,connect_by_root(ic.column_name) cbr
from dba_ind_columns ic,
dba_indexes i
where ic.table_owner=upper('&schema')
and ic.table_owner=i.table_owner
and ic.table_name=i.table_name
and ic.index_name=i.index_name
connect by prior ic.column_position-1=ic.column_position
and prior ic.index_name=ic.index_name )
group by table_owner,table_name,index_name,index_type,cbr ) ind
on cons.cols=ind.cols
and cons.table_name=ind.table_name
and cons.owner=ind.table_owner
order by checker,cons.owner,cons.table_name;
建立如下的测试表:
create table TEST_USER.students(stud_id number constraint pk_stud_id primary key,lname varchar2(40),fname varchar2(40));
create table TEST_USER.attendees
(stud_id number,
class_id number,
constraint pk_attendees primary key (stud_id,class_id)
);
alter table TEST_USER.attendees add constraint fk_stud foreign key (stud_id) references TEST_USER.students(stud_id);
执行第一个脚本,输出如下:
执行第二个脚本,输出如下: