关于truncate cascade 操作测试
一、参考官方文档语法说明
11g 语法:
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10007.htm#i2067571
12.1 之后语法:
https://docs.oracle.com/database/121/SQLRF/statements_10007.htm#i2067571
可以看到,12.1 之后,truncate 语法后面多了cascade 选项。
二、存在主外键关系的表truncate操作测试
11g 版本测试
--1) 创建主外键关系表
SQL> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(1000));
Table created.
SQL> ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID);
Table altered.
SQL> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(1000));
Table created.
SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID) ;
Table altered.
--2) 只插入父表数据,不插入子表数据
SQL> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
1985 rows created.
SQL> COMMIT;
Commit complete.
SQL> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
SQL> truncate table t_p cascade;
truncate table t_p cascade
*
ERROR at line 1:
ORA-03291: Invalid truncate option - missing STORAGE keyword
[oracle@ora11204 ~]$ oerr ora 2266
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";
--3) 继续插入子表数据,在执行truncate
SQL> INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) + 1, OBJECT_NAME FROM ALL_OBJECTS;
80953 rows created.
SQL> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
SQL> truncate table t_p cascade;
truncate table t_p cascade
*
ERROR at line 1:
ORA-03291: Invalid truncate option - missing STORAGE keyword
--4) 删除子表数据,在执行truncate操作
SYS@nocdb> truncate table t_c;
Table truncated.
SYS@nocdb> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
复制
结论:在11g 版本中,存在主外键关系的表,无论子表和父表中是否存在数据,父表都不支持truncate 操作。且11g 版本中,truncate 后面没有cascade选项。
12c 版本测试
场景1: 创建外键,不指定on delete 参数
--1) 创建主外键关系表
SYS@nocdb> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID);
Table altered.
SYS@nocdb> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID);
Table altered.
--2) 只插入父表数据,不插入子表数据
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
Table truncated.
--3) 继续插入子表数据,在执行truncate
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) + 1, OBJECT_NAME FROM ALL_OBJECTS;
71469 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
SYS@nocdb> truncate table t_p cascade;
truncate table t_p cascade
*
ERROR at line 1:
ORA-14705: unique or primary keys referenced by enabled foreign keys in table "SYS"."T_C"
--4) 删除子表数据,在执行truncate操作
SYS@nocdb> truncate table t_c;
Table truncated.
SYS@nocdb> truncate table t_p;
Table truncated.
复制
结论:创建外键不指定on delete 参数时候, 若子表中没有数据,那么父表可以直接truncate,若子表中存在数据,那么父表不允许truncate,即使加上cascade参数也不行。
场景2:创建外键,指定on delete set null
--1) 创建主外键关系表
SYS@nocdb> drop table t_p cascade constraints purge;
Table dropped.
SYS@nocdb> drop table t_c cascade constraints purge;
Table dropped.
SYS@nocdb> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID);
Table altered.
SYS@nocdb> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID) on delete set null;
Table altered.
--2) 只插入父表数据,不插入子表数据
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
Table truncated.
--3) 继续插入子表数据,在执行truncate
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) + 1, OBJECT_NAME FROM ALL_OBJECTS;
71469 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
SYS@nocdb> truncate table t_p cascade;
truncate table t_p cascade
*
ERROR at line 1:
ORA-14705: unique or primary keys referenced by enabled foreign keys in table "SYS"."T_C"
--4) 删除子表数据,在执行truncate操作
SYS@nocdb> truncate table t_c;
Table truncated.
SYS@nocdb> truncate table t_p;
Table truncated.
复制
结论:和场景1 不指定on delete参数结论一样。
场景3:创建外键,指定on delete cascade
--1) 创建主外键关系表
SYS@nocdb> drop table t_p cascade constraints purge;
Table dropped.
SYS@nocdb> drop table t_c cascade constraints purge;
Table dropped.
SYS@nocdb> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID);
Table altered.
SYS@nocdb> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(1000));
Table created.
SYS@nocdb> ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID) on delete cascade;
Table altered.
--2) 只插入父表数据,不插入子表数据
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
Table truncated.
--3) 继续插入子表数据,在执行truncate
SYS@nocdb> INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
2213 rows created.
SYS@nocdb> INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) + 1, OBJECT_NAME FROM ALL_OBJECTS;
71469 rows created.
SYS@nocdb> COMMIT;
Commit complete.
SYS@nocdb> truncate table t_p;
truncate table t_p
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
SYS@nocdb> truncate table t_p cascade;
Table truncated.
SYS@nocdb> select count(*) from t_p;
COUNT(*)
----------
0
SYS@nocdb> select count(*) from t_c;
COUNT(*)
----------
0
复制
结论:创建外键指定on delete cascade参数时候, 若子表中没有数据,那么父表可以直接truncate,若子表中存在数据,那么父表不允许truncate,但是加上cascade参数后,truncate操作成功,且连体子表中数据一起被truncate。
三、结论
综上测试可以看到:
- 在11g 版本中,无论子表中是否存在数据,父表都不可以执行truncate操作。
- 在12c 版本中,不管是否指定on delete参数,只要子表中没有数据,那么父表就可以执行truncate操作,这点比11g 有所增强。
- 在12c 版本中,只有指定了on delete cascade参数,那么在子表存在数据的情况下,可以通过truncate cascade 命令同时删除父表和子表中数据。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年3月中国数据库排行榜:PolarDB夺魁傲群雄,GoldenDB晋位入三强
墨天轮编辑部
1669次阅读
2025-03-11 17:13:58
【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化
墨天轮编辑部
1243次阅读
2025-03-06 16:45:38
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1224次阅读
2025-03-13 11:40:53
01. HarmonyOS Next应用开发实践与技术解析
若城
1180次阅读
2025-03-04 21:06:20
DeepSeek R1助力,腾讯AI代码助手解锁音乐创作新
若城
1162次阅读
2025-03-05 09:05:00
03 HarmonyOS Next仪表盘案例详解(二):进阶篇
若城
1161次阅读
2025-03-04 21:08:36
05 HarmonyOS NEXT高效编程秘籍:Arkts函数调用与声明优化深度解析
若城
1153次阅读
2025-03-04 22:46:06
04 高效HarmonyOS NEXT编程:ArkTS数据结构优化与属性访问最佳实践
若城
1144次阅读
2025-03-04 21:09:35
02 HarmonyOS Next仪表盘案例详解(一):基础篇
若城
1139次阅读
2025-03-04 21:07:43
06 HarmonyOS Next性能优化之LazyForEach 列表渲染基础与实现详解 (一)
若城
1134次阅读
2025-03-05 21:09:40