Oracle 11g用DBMS_REDEFINITION迁分区表后非空列显示异常
解决Oracle 11g DBMS_REDEFINITION迁移分区表后非空列显示NULLABLE YES的问题
这是Oracle 11g使用DBMS_REDEFINITION进行在线表重定义时的典型局限——11g版本的工具不会将原表的列级NOT NULL约束直接迁移到新分区表,而是自动转换为**CHECK(列 IS NOT NULL)**约束,这就导致数据字典里列的NULLABLE属性显示为YES,但实际的非空限制是完全生效的。
问题根源
Oracle 11g的在线重定义机制在处理分区表转换时,对非空约束的处理逻辑和12.2及以后版本有差异:12.2+支持直接保留列级NOT NULL属性,但11g只能通过创建CHECK约束来等效实现非空限制,因此列本身的NULLABLE标记不会同步更新。
验证约束有效性
你可以通过查询数据字典确认这些CHECK约束的存在:
SELECT cc.table_name, cc.column_name, c.constraint_name, c.search_condition FROM user_constraints c JOIN user_cons_columns cc ON c.constraint_name = cc.constraint_name WHERE c.constraint_type = 'C' AND c.search_condition LIKE '%IS NOT NULL';
执行后会看到所有原非空列对应的CHECK约束,这些约束和列级NOT NULL的功能完全一致,都会阻止插入或更新NULL值。
让列级显示正确的NOT NULL属性
如果希望数据字典里的NULLABLE属性显示为NO,可以在重定义完成后执行以下操作:
- 针对每个受影响的列,修改列属性:
由于已有CHECK约束保证列非空,这个操作不会触发全表数据检查,执行速度很快。ALTER TABLE your_target_table MODIFY (your_column NOT NULL); - (可选)如果不需要重复约束,可以删除对应的CHECK约束:
ALTER TABLE your_target_table DROP CONSTRAINT your_check_constraint_name;
另外,也可以在重定义流程的创建中间表阶段,手动指定列的NOT NULL属性,再启动重定义。这样新表的列一开始就会有正确的NULLABLE标记,不过需要确保中间表的结构完全匹配原表(包括索引、其他约束等)。
额外说明
即使不修改列的NULLABLE属性,CHECK约束也能完全替代列级NOT NULL的功能,不会影响业务逻辑。如果对数据字典的显示没有强制要求,也可以保留现状,无需额外操作。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

