引起ORA-12991 问题可能的第4个原因
一、问题产生背景
进行指定表中某个字段的数据类型变更时,由于该字段中存在历史数据,因此需要:
1)新建一个临时字段并将历史数据进行赋值;
2)将原始字段删除;
3)临时字段更名为原始字段名。
执行第2)步时,Oracle报错:ORA-12991: column is referenced in a multi-column constraint(引用的列处于多列约束条件)。
二、问题调查和解决
1. check被删除的列所在的表是否存在该列的外键约束:如果有,则删除对应的列约束;如果没有,继续下一步查询。
SQL:
SELECT a.table_name,a.column_name,a.constraint_name,b.constraint_type
FROM user_cons_columns a,user_constraints b
WHERE a.table_name='target_table_name' AND a.column_name='target_column'
AND b.constraint_type='R' AND a.constraint_name=b.constraint_name;
2. 扩大约束限制查询:如果有,则删除对应的列约束;如果没有,继续下一步查询。
SQL:
SELECT a.table_name,a.column_name,a.constraint_name,b.constraint_type
FROM user_cons_columns a,user_constraints b
WHERE a.table_name='target_table_name' AND a.column_name='target_column'
AND a.constraint_name=b.constraint_name;
3. check被删除的列是否存在索引:若存在则删除;如果没有,继续下一步查询。
4. 当该列既无约束,又无索引时,需要检查Oracle 的补充日志(Supplemental Logging)中是否存在该表的记录:
SQL:
select * from user_log_groups where table_name = 'target_table_name';
如果查询结果不为空时,获取LOG_GROUP_NAME后,进行删除操作:
SQL:
alter table target_table_name drop supplemental log group LOG_GROUP_NAME;
5.当按照上述步骤检查和执行完后,再重新执行列删除即可成功。
ps:本人遇到的情况正是第4个原因导致的。经分析,删除前进行了大量数据的Update操作。测试环境均无该问题,只有生产环境出现,生产环境是Oracle集群,且启用了补充日志。
三、相关资料
1. Oracle 表中字段的约束类型释义:
2. Oracle 补充日志:
只要是针对 UPDATE 命令的,是对重做日志记录中变更矢量块的补充信息,增加了变更矢量记载的记录量。
日志挖掘器(LogMiner)、闪回事务查询、闪回事务等都需要补充日志的支持。尤其是日志挖掘器如果发现未启用补充日志,就拒绝服务。
也就是说补充日志主要是为UPDATE 命令服务的,补充的目的是高度还原 UPDATE 命令,避免因为update 命令造成的行迁移和行移动,
让LogMiner 通过分析重做日志中识别 update 命令 不是 由 insert 和 delete 完成的。
如果未启用补充日志,重做日志只将 UPDATE 命令更改的字段的旧值保存在撤销数据块的变更矢量中。而在数据块中的变更矢量中记载被修改后的字段的新值。同行中的未被修改的字段,不会被记载。
如果启用了补充日志,重做日志中的撤销数据块的变更矢量中会记录被修改字段前的值和修改后的值,而且还会记录修改字段的那个条件的值。即变更矢量中会记载:几号数据文件+几号文件中的几号块+第几个字段+修改后的值+修改前的值+“where 条件” 的值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了