【问题标题】:Alter table enable novalidate constraint更改表启用 novalidate 约束
【发布时间】:2017-08-11 15:43:34
【问题描述】:

我正在尝试通过设置 ENABLE NOVALIDATE 在先前存在的具有重复记录的表上添加 UNIQUE KEY

但我收到ORA-02299: cannot validate (my_owner.my_key_UK ) - duplicate keys found

ALTER TABLE my_owner.my_table
ADD CONSTRAINT my_key_UK UNIQUE (ID1,ID2)
ENABLE NOVALIDATE;

【问题讨论】:

标签: oracle plsqldeveloper


【解决方案1】:

唯一约束使用索引来强制执行 noduplicates 规则。默认情况下,它将创建一个唯一索引(有意义吗?)。正是这个索引创建正在引发ORA-02299

但是,如果这是受约束列上的现有索引,则约束将使用它。好消息是,索引不需要是唯一的,约束也可以使用它。

所以你需要做的是先建立一个非唯一索引:

create index whatever_idx on my_table (ID1,ID2);

然后你就可以创建你的约束了:

ALTER TABLE my_owner.my_table
ADD CONSTRAINT my_key_UK UNIQUE (ID1,ID2)
ENABLE NOVALIDATE;

您可以通过查询数据字典来检查:

select uc.constraint_name
       , uc.constraint_type
       , uc.index_name
       , ui.uniqueness as idx_uniqueness
from user_constraints uc
     join user_indexes ui
          on ui.index_name = uc.index_name
where uc.table_name = 'MY_TABLE'

【讨论】:

    【解决方案2】:

    Oracle 使用索引确保唯一值。如果您创建唯一约束 db 自动创建唯一索引。解决方法是添加 DEFERRABLE 选项。在这种情况下,oracle 创建普通索引。检查示例。

    create table table_abc (a number,b number);
    
    insert into table_abc values(1,1);
    insert into table_abc values(1,2);
    
    ALTER TABLE table_abc ADD CONSTRAINT my_key_a UNIQUE (a) DEFERRABLE enable novalidate; -- no error but in table nonunique values
    ALTER TABLE table_abc ADD CONSTRAINT my_key_b UNIQUE (b) ENABLE NOVALIDATE; --no error 
    
    select * from user_indexes where table_name ='TABLE_ABC';
    

    【讨论】:

    • Deferrable 是一个巧妙的技巧,但它确实改变了约束的行为,这可能会产生不良的副作用。
    • 我有大约 100 万的数据,其中有很多重复。我的要求是要插入的新数据应该具有唯一性。那么,您能否解释一下如果使用 DEFERRABLE,约束可能会发生哪些行为变化?
    • @APC 有什么副作用?
    • @Neeraj DEFERRABLE 如果您不进行任何更改,则可以正常工作。如果您执行SET CONSTRAINTS my_key a DEFERRED,则在提交期间将检查约束。
    • @Neeraj 如果你删除 DEFERRABLE 会限制 oracle 不会自动删除背景索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 2018-01-16
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多