存在外键关联的主表truncate如何做

主外键是数据库提供的一种两表之间强制关联的方法,也可以从应用层实现。

优点 缺点
数据库实现的主外键 由数据库层机制保证,无需应用额外实现 强关联,不易扩展变更
应用实现的主外键 易扩展变更 完全由应用控制,要求较高

我认为需要根据实际情况进行取舍,例如表不复杂,可以由应用实现,若表之间关联较多且复杂,那么交由数据库处理,至少保证不会错。

存在主外键关联的主表,由于存在外键关联关系,因此有些操作就会禁止,例如truncate。

实验

1. 创建测试表

SQL> create table tbl_a(id number, remark varchar2(1));
Table created.

SQL> create table tbl_b(id number, a_id number, remark varchar2(1));
Table created.

SQL> alter table tbl_a add constraint pk_tbl_a primary key(id);
Table altered.

SQL> alter table tbl_b add constraint pk_tbl_b primary key(id);
Table altered.

SQL> alter table tbl_b add constraint fk_tbl_b_a foreign key(a_id) references tbl_a(id);
Table altered.

tbl_a是主表,tbl_b是子表,关联tbl_a。

2. 现在主表和子表没有任何数据,此时执行truncate主表

SQL> truncate table tbl_a;
Table truncated.

可以执行。

3. 向主表插入一条记录,再次执行truncate

SQL> insert into tbl_a values(1, 'a');
1 row created.

SQL> commit;
Commit complete.

SQL> truncate table tbl_a;
truncate table tbl_a
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys

此时提示了ORA-02266:唯一/主键被启用的外键引用

看看ORA-02266的解释:

02266, 00000, "unique/primary keys in table referenced by enabled foreign keys"
// *Cause: An attempt was made to truncate a table with unique or
//         primary keys referenced by foreign keys enabled in another table.
//         Other operations not allowed are dropping/truncating a partition of a
//         partitioned table or an ALTER TABLE EXCHANGE PARTITION.
// *Action: Before performing the above operations the table, disable the
//          foreign key constraints in other tables. You can see what
//          constraints are referencing a table by issuing the following
//          command:
//          SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME = "tabnam";

比较清楚地说明了问题,以及解决方法:可以在执行前,先禁用外键约束,执行truncate后再恢复外键约束。

4. 禁用外键约束,删除后执行恢复操作

看到外键约束名称:FK_TBL_B_A:

SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
PK_TBL_B                       P ENABLED
FK_TBL_B_A                     R ENABLED

禁止外键约束:

SQL> alter table tbl_b disable constraint FK_TBL_B_A;

Table altered.

SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
PK_TBL_B                       P ENABLED
FK_TBL_B_A                     R DISABLED

STATUS状态变为DISABLED了。

truncate表:

SQL> truncate table tbl_a;

Table truncated.

恢复约束:

SQL> alter table tbl_b enable constraint FK_TBL_B_A;

Table altered.

SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';

CONSTRAINT_NAME                C STATUS
------------------------------ - --------
PK_TBL_B                       P ENABLED
FK_TBL_B_A                     R ENABLED

总结:

1. 主外键是数据库提供的强约束,可以帮助我们控制主子表之间的关系,但同时还是一把双刃剑,当然,我们认为既然定义了主外键,就是需要这种强制关系,但有时可能就会有一些变更,因此,如何取舍,需要根据实际情况来决策。

2. 主外键关联中的主表,如果有数据,则不能直接用truncate方式删除,因为会认为有外键和其关联,不能直接截断主表,若需要做,可以先禁止外键约束,主表变成一个独立的表,这样就可以执行truncate了。



时间: 2024-10-23 20:08:17

存在外键关联的主表truncate如何做的相关文章

Java的Hibernate框架中的双向主键关联与双向外键关联_java

一.双向主键关联双向的主键关联其实是单向一对一主键关联的一种特殊情况,只不过要在关联对象的两端的映射文件中都要进行<one-to-one>的配置,另外还要在主映射的主键一端采用foreign外键关联属性. 这里同样使用Person和IdCard来讨论,一个人对应着一个唯一的身份证,而且一个身份证也唯一映射着一个人,所以这就产生了双向的关联关系,Person的主键同样也是IdCard的主键,分别是主键的同时也是外键,这种关联关系成为双向一对一映射,表现到关系模型中可如下图: 图中的两个表采用了主

主外键关联删除(on delete set null和on delete cascade)

主外键关联,当删除的是父表数据,参照这些要删除的数据,Oracle有三种处理方式: 1.禁止删除,也是Oracle默认方法. 2.将参照要删除数据的子表对应数据置空. 3.将参照要删除数据的子表对应数据删除. 对于1,比较容易理解,不解释. 对于2,需要使用on delete set null建立外键约束.实验: create table dept_test(deptno number(10) not null, deptname varchar2(30) not null, constrain

系统学习hibernate之六:一对一外键关联映射双向关联

hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard) 一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载 其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系, 所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式: <one-to-one name="person"

系统学习hibernate之五:一对一外键关联

在hibernate中一对一外键关联跟多对一外键关联有很相似的地方, hibernate多对一外键关联先参考这个,然后只要是在*.hbm.xml里面加入以下代码: <many-to-one name="group" column="groupid" unique="true"/>, 就是加入unique="true"属性. 多对一外键关联中的*.hbm.xml里面加入以下代码:<many-to-one nam

在Hibernate框架中编写持久对象类实现外键关联的几点注意事项

关系数据库系统本身就比较复杂,加上Hibernate的O/R映射层,复杂度加重了,很容易出现问题,本人将最近遇到的问题和解决方法做一个总结,整理在下面的一系列文章中 正确理解Hibernate的聚合类型(collection)的使用 在Hibernate中正确实现关联关系中的级联操作(cascading) 在Hibernate框架中编写持久对象类实现外键关联的几点注意事项 本文是第三篇,讲解在one-to-many(一对多)关联关系中的对象类的几个关键方法的实现.主要是equals(),hash

oracle中如何判断本表有多少张表对其有外键关联

在oracle中如何判断本表有多少张表对其有外键关联?我们主要分为两步: 第一步:        //查询表的主键约束名 select * from user_constraints e where e.table_name='' -----此处输入表名 第二步:        //查询所有引用到该主键的记录 select b.table_name,b.column_name from user_constraints a inner join user_cons_columns b on a.

oracle修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变

问题描述 oracle修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变 oracle 中修改一个表中的主键字段值,与其外键关联的另一个表中的相应字段值也改变? 有如下两张表,表a和表b 表a 结构如下: ID Name age 1 lisi 18 2 wangwu 21 3 sunliu 34 4 yiliu 24 ... ... ... 其中ID字段为表a主键且自增 表b结构如下: CID CNAME ID 1 aaaaa 1 2 bbbbb 2 3 cccccc 4 4

hibernate5(12)注解映射[4]一对一外键关联

在实际博客网站中,文章内容的数据量非常多,它会影响我们检索文章其它数据的时间,如查询发布时间.标题.类别的等.这个时候,我们可以尝试将文章内容存在另一张表中,然后建立起文章--文章内容的一对一映射 一对一关联有两种方式,一种是外键关联,另一种是复合主键关联. 外键关联 下面我们先看一个一对一单向关联的实例 /*************关联关系维护方************/ @Table(name = "t_article") @Entity public class Article

Hibernate一对一单向外键关联(简单总结了5种方法)

比如一对夫妻,丈夫有id,name:妻子有id,name.增加一对一单向外键关联一般有以下几种方法: 1.在husband中增加一个外键,foreign key 2.在husband中增加字段wife_id,wife_id参照wife的id.以wife为主导,必须wife里有id才能参照 3.在wife中增加一个外键,foreign key 4.在wife中增加字段husband_id,husband_id参照husband的id.以hunsband为主导,必须hunsband里有id才能参照