暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

关于truncate cascade 操作测试

原创 心在梦在 2024-03-06
490

关于truncate cascade 操作测试

一、参考官方文档语法说明

11g 语法:

https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10007.htm#i2067571
图片.png
 

12.1 之后语法:

https://docs.oracle.com/database/121/SQLRF/statements_10007.htm#i2067571

图片.png
 

可以看到,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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论