开发提了个需求,要求将测试数据库的数据清空,其中涉及主子表的关系,如下所示,

最直观的做法,就是truncate表。首先truncate各个子表,但是当执行truncate主表的时候,提示错误,ORA-02266: unique/primary keys in table referenced by enabled foreign keys。

子表此时没数据,为何不让删除主表的数据?

我们模拟下过程,首先创建测试表,主表a_1,子表b_1,

SQL> create table a_1 (id number);Table created.SQL> create table b_1 (id number, id_a_1 number);Table created.SQL> alter table a_1 add constraint pk_a_1 primary key(id);Table altered.SQL> alter table b_1 add constraint fk_b_a foreign key (id_a_1) references a_1 (id);Table altered.Table created.

SQL> create table b_1 (id number, id_a_1 number);Table created.

SQL> alter table a_1 add constraint pk_a_1 primary key(id);Table altered.

SQL> alter table b_1 add constraint fk_b_a foreign key (id_a_1) references a_1 (id);Table altered.

此时truncate子表和主表,均会成功,

SQL> truncate table b_01;Table truncated.SQL> truncate table a_01;Table truncated.Table truncated.

SQL> truncate table a_01;Table truncated.

但是,当主子表有数据,truncate子表,再做truncate主表的操作,就会提示ORA-02266的错误,

SQL> insert into a_1 values(1);1 row created.SQL> insert into b_1 values(1,1);1 row created.SQL> commit;Commit complete.SQL> truncate table b_1;Table truncated.SQL> truncate table a_1;truncate table a_1               *ERROR at line 1:ORA-02266: unique/primary keys in table referenced by enabled foreign keys1 row created.

SQL> insert into b_1 values(1,1);1 row created.

SQL> commit;Commit complete.

SQL> truncate table b_1;Table truncated.

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

ORA-02262的错误含义是,“表中的唯一/主键被启用的外键引用”,

02262, 00000, "ORA-%s occurs while type-checking column default value expression"// *Cause:  New column datatype causes type-checking error for existing column//        default value expression.// *Action: Remove the default value expression or don't alter the column//        datatype.// *Cause:  New column datatype causes type-checking error for existing column//        default value expression.// *Action: Remove the default value expression or don't alter the column//        datatype.

但是子表已经没数据了,主表怎么还会提示这个错误?究其原因,这和truncate操作有关,因为truncate是DDL,但是DDL语句不会检查约束,换句话说,他不知道子表有没有数据依赖于他,索性不让做了。

但是有个疑问,当主子表无数据,此时truncate主表,是可以成功的,只有当主子表有数据的时候,truncate主表才会提示。我看了下统计信息中,表中无数量记录,Oracle是如何知道当前表有数据,禁止truncate?

我猜测,可能是延迟段的影响?

1. 看下表中有数据,执行truncate产生的10046,其中truncate table a_1主表时,有个绑定变量的参数是B_1,推测由此知道a_1有外键引用,进而报错,err=2266

...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...truncate table a_1...Bind#1  oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00  oacflg=10 fl2=0001 frm=01 csi=873 siz=0 off=24  kxsbbbfp=7f2df926afc8  bln=32  avl=03  flg=01  value="B_1"...ERROR #139835430202688:err=2266 tim=1562853681567125...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...truncate table a_1...Bind#1  oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00  oacflg=10 fl2=0001 frm=01 csi=873 siz=0 off=24  kxsbbbfp=7f2df926afc8  bln=32  avl=03  flg=01  value="B_1"...ERROR #139835430202688:err=2266 tim=1562853681567125...

2. 看下表中无数据,执行truncate产生的10046,发现他会检索deferred_stg$视图,truncate是靠aw_trunc_proc存储过程

...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...select pctfree_stg, pctused_stg, size_stg,initial_stg, next_stg, minext_stg, maxext_stg, maxsiz_stg, lobret_stg,mintim_stg, pctinc_stg, initra_stg, maxtra_stg, optimal_stg, maxins_stg,frlins_stg, flags_stg, bfp_stg, enc_stg, cmpflag_stg, cmplvl_stg from deferred_stg$ where obj# =:1...truncate table a_1...BEGIN  aw_trunc_proc(ora_dict_obj_type, ora_dict_obj_name, ora_dict_obj_owner);END;...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...select pctfree_stg, pctused_stg, size_stg,initial_stg, next_stg, minext_stg, maxext_stg, maxsiz_stg, lobret_stg,mintim_stg, pctinc_stg, initra_stg, maxtra_stg, optimal_stg, maxins_stg,frlins_stg, flags_stg, bfp_stg, enc_stg, cmpflag_stg, cmplvl_stg from deferred_stg$ where obj# =:1...truncate table a_1...BEGIN  aw_trunc_proc(ora_dict_obj_type, ora_dict_obj_name, ora_dict_obj_owner);END;...

3. 关闭session级别的延迟段特性

gment_creation=false;

Session altered.

表中无数据,执行truncate产生的10046,和上面两个比,操作最简单,LOCK表,执行truncate,没其他操作了

...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...truncate table a_1...LOCK TABLE "A_1" IN EXCLUSIVE MODE  NOWAIT...truncate table a_1...

从现象看,不是延迟段特性,导致两者的区别,需要请大佬指教。

针对ORA-02266的错误,有几种解决方案,


方案1:禁用约束-truncate-启用约束

可以参考MOS这篇文章《OERR: ORA-2266 "unique/primary keys in table referenced by enabled foreign keys" Reference Note (Doc ID 19499.1)》。

1. 找出主表的约束

SELECT constraint_nameFROM user_constraintsWHERE table_name = '<table_you_are_trying_to_drop>'AND constraint_type = 'P';SELECT *FROM user_constraintsWHERE constraint_type = 'R'AND r_constraint_name = '<constraint_name_returned_above>';FROM user_constraintsWHERE table_name = '<table_you_are_trying_to_drop>'AND constraint_type = 'P';

SELECT *FROM user_constraintsWHERE constraint_type = 'R'AND r_constraint_name = '<constraint_name_returned_above>';

或者执行下列任意一个SQL,都可以得到主键相关的外键参考

select a.constraint_type,a.table_name,a.status, b.table_name,b.column_name,b.constraint_name from user_constraints ainner join user_cons_columns b on a.constraint_name = b.constraint_namewhere a.r_constraint_name='主键约束名称';select c.TABLE_NAMEfrom all_constraints p, all_constraints cwhere p.table_name = '主键约束名称'and p.OWNER = SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')and c.OWNER=SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')and c.constraint_type = 'R'and p.CONSTRAINT_NAME = c.R_CONSTRAINT_NAME;inner join user_cons_columns b on a.constraint_name = b.constraint_namewhere a.r_constraint_name='主键约束名称';

select c.TABLE_NAMEfrom all_constraints p, all_constraints cwhere p.table_name = '主键约束名称'and p.OWNER = SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')and c.OWNER=SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')and c.constraint_type = 'R'and p.CONSTRAINT_NAME = c.R_CONSTRAINT_NAME;

2. 删除约束

SQL> alter table a_1 disable primary key cascade;Table altered.Table altered.

3. 执行truncate

4. 启用约束

只是需要注意,enable恢复主键的操作,并不会自动enable外键,需要手工enable外键

SQL> alter table tbl_a enable primary key;Table altered.SQL> alter table tbl_b enable constraint fk_b_a;Table altered.Table altered.

SQL> alter table tbl_b enable constraint fk_b_a;Table altered.

方案2:delete删除

使用delete,DML操作是可以正常删除主表,只是不适合数据量很大的场景。

扩展阅读


  1. 美女DBA带你了解PostgreSQL用户及角色

  2. 分布式锁用Redis坚决不用Zookeeper?

  3. 频发:记ADG备库日志应用延迟的一次故障处理-云和恩墨技术通讯精选

  4. MySQL锁的灵魂七拷问

  5. 从Oracle到PostgreSQL:最全控制文件

数据和云

ID:OraNews

如有收获,请划至底部,点击“在看”,谢谢!


公司简介  | 招聘 | DTCC | 数据技术嘉年华 | 免费课程 | 入驻华为严选商城

zCloud | SQM | Bethune Pro2 | zData一体机 | MyData一体机 | ZDBM 备份一体机

Oracle技术架构 | 免费课程 | 数据库排行榜 | DBASK问题集萃 | 技术通讯

升级迁移 | 性能优化 | 智能整合 | 安全保障 |  架构设计 | SQL审核 | 分布式架构 | 高可用容灾 | 运维代维

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

一次执行truncate触发ORA-02266解决过程相关推荐

  1. oracle错误01653,oracle 10g 错误 ORA 01653 的解决过程

    oracle 10g 错误 ORA 01653 的解决过程 早上用户反应在操作用友NC时报错 ORA-01653 ,详细信息:ORA-01653: 表 NCV35.GL_DETAIL 无法通过 102 ...

  2. 执行truncate引发ORA-02266的问题分析

    墨墨导读:将测试数据库的数据清空,其中涉及主子表的关系,执行truncate产生的ORA-02266问题处理过程. 1. 超实用的几个公众号推荐 2. 赠书:<Oracle Exadata专家手 ...

  3. onload js函数不执行的原因分析及解决方法

    今天打开网站的时候,发现很多页面的信息都没有显示出来,仔细观察了之后,发现都是onload的js函数没有执行的原因.其实之前曾发现过这个情况,我以为是网站出了问题,然后采用多种方法试图让onload的 ...

  4. 对一个元素 同时添加单击onclick 和 双击ondblclick 触发冲突的解决

    需求说明:单击列表项内容后,吧啦吧啦,双击列表项内容后,巴拉巴拉巴拉~~~ 解决思路:卧槽 ,其实我是没思路的,当时唯一的想法就是,看个人点击鼠标的速度了,双击快一点,触发双击事件ლ(′◉❥◉`ლ), ...

  5. ORA -01034解决

    ORA - 01034 转:ORA-01034和ORA-27101的解决方法 个人小结: 输入sqlplus /nolog,回车 输入 conn / as sysdba;回车 输入 startup p ...

  6. oracle执行先决条件检查失败的解决方法

    oracle执行先决条件检查失败的解决方法 参考文章: (1)oracle执行先决条件检查失败的解决方法 (2)https://www.cnblogs.com/xiaoxiaoweng/p/72779 ...

  7. mysql 安装问题一:由于找不到MSVCR120.dll,无法继续执行代码.重新安装程序可能会解决此问题。

    mysql 安装问题一:由于找不到MSVCR120.dll,无法继续执行代码.重新安装程序可能会解决此问题. 参考文章: (1)mysql 安装问题一:由于找不到MSVCR120.dll,无法继续执行 ...

  8. [Unity] AnimationEvent 因 Animator Controller 中 Transition 设置问题而不触发的快速解决办法:重新拖入 Animator 创建新 State

    这篇文章提出了一个 AnimationEvent 不触发的可能性:Animator Controller 中 Transition 设置问题 https://blog.csdn.net/qq_4173 ...

  9. 由于找不到MSVCR120.dll,无法继续执行代码.重新安装程序可能会解决此问题。

    由于找不到MSVCR120.dll,无法继续执行代码.重新安装程序可能会解决此问题. 解决办法: 这种错误是由于未安装 vcredist 引起的,根据自己操作系统版本下载对应的安装文件. 下载地址:h ...

最新文章

  1. Python 优化第一步: 性能分析实践 使用cporfile+gprof2dot可视化
  2. Java 8系列之重构和定制收集器
  3. c语言规定 函数返回值6,C语言六函数.ppt
  4. Kafka 为什么能那么快的 6 个原因
  5. 从感知机到支持向量机—学习笔记
  6. JavaScript 运行机制详解:再谈Event Loop
  7. 随便说说Silverlight
  8. 强悍修改WIN7的文件夹背景(修改DLL)
  9. 华为ac配置radius认证服务器_华为AAA结合Radius服务器认证学习
  10. 终于有人把分布式机器学习讲明白了
  11. cad卸载不干净_【实用】流氓软件卸载不干净?
  12. 论文学习笔记——弱监督语义分割(Learning Integral Objects with Intra-Class Discriminator for Weakly-Supervised Sema)
  13. Android 65536错误:Cannot fit requested classes in a single dex file
  14. 检测按键正确的小游戏
  15. 使用Vmalert监控报警
  16. 使用小程序制作一个电子木鱼,功德+1
  17. 友友球捕获率_口袋妖怪精灵球大科普,大师球能捕捉创世神吗?
  18. GB/T 7714-2015 Enenote参考文献模板免费下载
  19. 【动画演示软件】Focusky教程 | Focusky中超链接基础运用
  20. 华中科技大学_计算机学院_计算机系统结构课程笔记

热门文章

  1. taz文件_我们将赠送LulzBot Taz 6 3D打印机
  2. 业务分析岗所需具备的技能_成功的业务分析师需要具备的3种技能
  3. openstack 功能_2016年OpenStack的新功能:看一下Newton版本
  4. 数据战略规划_在战略规划期间我应该如何协作?
  5. 苹果的Swift 2.0,Raspberry Pi Zero vs CHIP以及更多新闻
  6. 警钟 | 还不会Spring Boot集成JWT,你可能错过了大厂的Office了
  7. HTML5 Canvas save 保存恢复状态
  8. es6 Mixin 模式的实现
  9. [转]google protobuf安装与使用
  10. python监控linux运行程序_如何在linux/tcl/python中监控正在打开或启动的应用程序?...