如何修改现有的检查约束?

sch*_*rik 68 oracle ora-00933

除了删除和重新创建之外,有没有办法修改表上的现有检查约束 ?

create table t ( n number);
ora10g> Tabelle wurde erstellt.

ora10g> alter table t add constraint ck check(n>0);

Tabelle wurde geõndert.

ora10g> alter table t modify constraint ck check(n<0);
alter table t modify constraint ck check(n<0)
                                   *
FEHLER in Zeile 1:
ORA-00933: SQL-Befehl wurde nicht korrekt beendet
Run Code Online (Sandbox Code Playgroud)

Ada*_*sch 117

您必须删除它并重新创建它,但如果您不想这样做,则不必承担重新验证数据的成本.

alter table t drop constraint ck ;
alter table t add constraint ck check (n < 0) enable novalidate;
Run Code Online (Sandbox Code Playgroud)

enable novalidate子句将强制插入或更新以强制执行约束,但不会强制对表执行全表扫描以验证所有行是否符合.

  • 针对表的 DDL 需要针对它的 X 锁,但事务可能会潜入两者之间。我想更好的方法是创建新约束,删除旧约束,将新约束重命名为旧约束名称。然而,在发布的案例中,这两个约束是互斥的。 (3认同)
  • 如果没有与数据库的连接,这很好。在一般情况下进行更改之前,请参阅[此](/sf/answers/3101128831/)答案。 (2认同)

Wit*_*rba 6

首先创建一个新约束,然后删除旧约束。
这样,您可以确保:

  • 约束始终存在
  • 现有行不违反新约束
  • 在删除约束之后且在应用新约束之前,不会尝试进行任何非法的INSERT / UPDATE。

  • @ThatsMe 为什么要使用最终名称创建新约束的第二个副本?为什么不跳过步骤 3 并将临时约束重命名为原始约束呢? (3认同)
  • 您仍然可以采取一个技巧:1/使用临时名称创建新约束。2/删除原来的约束,这样它的名字就可用了。3/ 创建新约束的第二个副本及其最终名称。4/ 删除临时约束。 (2认同)
  • @DagdA 你说得完全正确!你有这个检查约束: alter table test add constraint chk_id check (0 &lt; id); 你想改变它: alter table test add constraintmp_id check (1 &lt;= id); 更改表测试删除约束 chk_id;alter table test 将约束 tmp_id 重命名为 chk_id; (2认同)