操作目的:
由于表空间不足,truncate table TIP_INSTANCE 释放表空间。
准备工作:
将该表exp备份出来
exp user/userpwd buffer=64000000 FEEDBACK=1000000 INDEXES=y direct=y tables=TIP_INSTANCE file=/dsg/fgy/TIP_INSTANCE090309.dmp
遇到的问题:
question 1
truncate table TIP_INSTANCE;
报错如下:
ORA-02266: 表中的唯一/主键被启用的外部关键字引用;
于是开始查看其所关联的表:
select * from dba_constraints where r_constraint_name='PK_TIP_INSTANCE'; --PK_TIP_INSTANCE是在表TIP_INSTANCE上建立的主键
查到其外键为FK_TIP_INST_REFERENCE_TIP_INST;
查到ORA-02266报错问题原因是:TIP_INSTANCE的主键关联所致。
于是才去下面方法:
alter table TIP_INSTANCE disable primary key cascade;
truncate table TIP_INSTANCE;
alter table TIP_INSTANCE enable primary key;
并对相关表的索引进行重建,表分析,日志如下:
SQL> alter table TIP_INSTANCE disable primary key cascade;
Table altered
SQL> truncate table TIP_INSTANCE;
Table truncated
SQL> alter table TIP_INSTANCE enable primary key;
Table altered
SQL> alter index PK_TIP_INSTANCE rebuild online nologging;
Index altered
SQL> alter index PK_TIP_INSTANCE_LIST rebuild online nologging;
Index altered
SQL> alter index INTERFACODULE_ID_IDX rebuild online nologging;
Index altered
SQL> exec dbms_stats.gather_table_stats('user','TIP_INSTANCE',degree => 100,cascade => true);
PL/SQL procedure successfully completed
SQL> exec dbms_stats.gather_table_stats('user','TIP_INSTANCE_LIST',degree => 100,cascade => true);
PL/SQL procedure successfully completed
但是做完后查看发现了下面的问题:
question 2
SQL> select constraint_name,status from dba_constraints where r_constraint_name='PK_TIP_INSTANCE';
CONSTRAINT_NAME STATUS
------------------------------ --------
FK_TIP_INST_REFERENCE_TIP_INST DISABLED
为啥这个外键是disabled的呢??
于是开始设法操作其状态为enable:
SQL> alter table sps.TIP_INSTANCE_list enable constraint FK_TIP_INST_REFERENCE_TIP_INST;
ORA-02298: 无法验证 (SPS.FK_TIP_INST_REFERENCE_TIP_INST) - 未找到父项关键字
这个问题 ORA-02298 的原因是什么呢?
问题原因就是:
主键所属表TIP_INSTANCE已经被truncate了,但是 TIP_INSTANCE_LIST 的外键是依据TIP_INSTANCE表的主键来建立的,
现在TIP_INSTANCE被truncate了,但是 TIP_INSTANCE_LIST没有truncate,导致呢TIP_INSTANCE_LIST里面以前通过外键跟TIP_INSTANCE 关联的那些数据呢,现在找不到关联了!!所以会报错“未找到父项关键字”
解决办法:
要么同理的 truncate表TIP_INSTANCE_LIST
要么将 TIP_INSTANCE_LIST 和 TIP_INSTANCE 以前关联的数据清理掉;
可以用下面语句来找相关联的数据:
select x.*
from TIP_INSTANCE_list x, TIP_INSTANCE y
where x.roleno = y.no(+)
and y.no is null;
总结:
这次的操作是我弄清楚了一件事情,在对一个拥有主键的表进行ddl操作的时候,要特地的去留意其是否关联有其他表的外键,如果有的话,进行truncate操作的时候呢,一定要注意:
将其truncate的话,依据其主键建立外键的表的外键是不可恢复的!!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9719235/viewspace-571436/ ,如需转载,请注明出处,否则将追究法律责任。