ITPub博客

首页 > Linux操作系统 > Linux操作系统 > primary key & foreign key 研究(一)

primary key & foreign key 研究(一)

原创 Linux操作系统 作者:xz831009 时间:2009-03-18 15:48:20 0 删除 编辑

目的:

这次做表空间清理的时候,碰到需要清理的A表建有主键,不需要清理的B表建有和A表主键关联的外键。将A表强制truncate后,导致B表的外键disabled,着实吓得不轻,此处暴露了wasd我对主键、外键使用的模糊,于是决定做实验来弄明白它们的使用关系。

准备:

数据库oracle9i,因为我的测试库只有三个表空间SYSTEMUNDOTBS1TEMP三个,所以我测试用的是sys用户,空间为system表空间。

---首先建表为了方便将两个表建成一致的表结构。

create table wasd_01(

wasd_id number,

wasd_name varchar2(10),

wasd_date date);

 

create table wasd_02(

wasd_id number,

wasd_name varchar2(10),

wasd_date date);

---插入初步测试数据

Insert into wasd_01 values(1,'wasd1',sysdate);

Insert into wasd_01 values(2,'wasd2',sysdate);

Insert into wasd_01 values(3,'wasd3',sysdate);

Insert into wasd_02 values(1,'wasd1',sysdate);

Insert into wasd_02 values(2,'wasd2',sysdate);

Insert into wasd_02 values(3,'wasd3',sysdate-1);

--给两个表赋予约束

SQL> alter table wasd_01 add (constraint pk_wasd_01 primary key (wasd_id,wasd_name)

 2 using index );

 Table altered

 SQL>

SQL> alter table wasd_02 add(constraint fk_wasd_02 foreign key (wasd_id,wasd_name)

 2 references wasd_01(wasd_id,wasd_name)) ;

Table altered

 

重现问题与解决:

wasd_01truncate

SQL> truncate table wasd_01;

 

truncate table wasd_01

ORA-02266:表中的唯一/主键被启用的外部关键字引用

下面强制truncatewasd_01

SQL> alter table wasd_01 disable primary key cascade ;

Table altered

SQL> truncate table wasd_01;

Table truncated

SQL> alter table wasd_01 enable primary key ;

Table altereds

SQL> select constraint_name,status from user_constraints where table_name like 'WASD_%';

CONSTRAINT_NAME               STATUS

------------------------------ --------

PK_WASD_01                    ENABLED

FK_WASD_02                    DISABLED这时wasd_02的外键已经失效了

 

SQL> alter table wasd_02 enable constraint fk_wasd_02;

alter table wasd_02 enable constraint fk_wasd_02

ORA-02298:无法验证(SYS.FK_WASD_02) -未找到父项关键字

如何来恢复呢??如何让wasd_02表的外键可用呢??

既然是在“未找到父项关键字”,那么我们就给它给“未找到父项关键字”:

SQL> Insert into wasd_01 values(1,'wasd1',sysdate);

1 row inserted

SQL> commit;

Commit complete

SQL> alter table wasd_02 enable constraint fk_wasd_02;

alter table wasd_02 enable constraint fk_wasd_02

ORA-02298:无法验证(SYS.FK_WASD_02) -未找到父项关键字

看来需要赋给其所有的“父项关键字”,继续:

SQL> Insert into wasd_01 values(2,'wasd2',sysdate-3);--注意这个地方

1 row inserted

SQL> Insert into wasd_01 values(3,'wasd3',sysdate);

1 row inserted

SQL> commit;

Commit complete

SQL> alter table wasd_02 enable constraint fk_wasd_02;

Table altered

SQL> select constraint_name,status from user_constraints where table_name like 'WASD_%';

 

CONSTRAINT_NAME               STATUS

------------------------------ --------

PK_WASD_01                    ENABLED

FK_WASD_02                    ENABLED

至此恢复成功。恢复的要点就是让wasd_02外键字段有的数据wasd_01也要有,如果直接做truncate table wasd_02,当然也是可以恢复外键的。

其他实验:

wasd_01进行dml操作

SQL> delete from wasd_01 where wasd_id=1;

delete from wasd_01 where wasd_id=1

ORA-02292:违反完整约束条件(SYS.FK_WASD_02) -已找到子记录日志说明要删除wasd_01wasd_02关联的数据会导致外键失效

SQL> insert into wasd_01 values (5,'wasd5',sysdate);

1 row inserted

SQL> rollback;

Rollback complete-说明wasd_01有的wasd_02没有是可以的

SQL> update wasd_01 set wasd_id=6 where wasd_id=1;

update wasd_01 set wasd_id=6 where wasd_id=1

ORA-02292:违反完整约束条件(SYS.FK_WASD_02) -已找到子记录日志解释同delete

SQL> update wasd_01 set wasd_id=7,wasd_name='wasd7' where wasd_id=1;

update wasd_01 set wasd_id=7,wasd_name='wasd7' where wasd_id=1

ORA-02292:违反完整约束条件(SYS.FK_WASD_02) -已找到子记录日志所有相关字段一块修改也不行

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9719235/viewspace-571437/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-12-20

  • 博文量
    13
  • 访问量
    17230