Oracle唯一约束删除和修改

时间:2015-11-02 12:54:05

标签: oracle11g constraints unique-constraint

我有一个表和2个约束 - 其中一个约束是微不足道的,我想从现有的表中删除它 - 它有数据。

以下是表格 -

create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));


insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');


alter table T1 add constraint T1_U unique (AA,BB);


alter table T1 add constraint T1_U1 unique (cc,dd);

现在,我们有2个约束,其中,我想删除T1_U1并修改 T1_U。

通过 -

可以看到2个约束
SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');

以下是我要遵循的步骤

  1. 禁用T1_U约束 -

    ALTER TABLE T1 DISABLE CONSTRAINT T1_U;

  2. 重命名索引 -

    ALTER INDEX T1_U1 RENAME TO T1_U;

  3. 删除T1_U。

    ALTER TABLE T1 DROP CONSTRAINT T1_U;

  4. 现在,如果我检查USER_OBJECTS,我仍然可以看到T1_U。 - 为什么会这样?

    所以我尝试使用DROP INDEX T1_U; - 这是不正确的。

    1. 然后我尝试修改T1_U - 按预期失败了。
    2. 问题:请告诉我有什么方法可以实现上述目标吗?

      感谢。

1 个答案:

答案 0 :(得分:1)

如果您还查看user_constraints:

,这很容易解释
create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));

insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');

alter table T1 add constraint T1_U unique (AA,BB);
alter table T1 add constraint T1_U1 unique (cc,dd);

SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');

OBJECT_NAME  OBJECT_TYPE        
------------ -------------------
T1_U         INDEX              
T1_U1        INDEX 

select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');

CONSTRAINT_NAME  CONSTRAINT_TYPE TABLE_NAME  STATUS   INDEX_NAME 
---------------- --------------- ----------- -------- -----------
T1_U             U               T1          ENABLED  T1_U
T1_U1            U               T1          ENABLED  T1_U1

存在约束及其相应的索引。

ALTER TABLE T1 DISABLE CONSTRAINT T1_U;

SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');

OBJECT_NAME  OBJECT_TYPE        
------------ -------------------
T1_U1        INDEX

select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');

CONSTRAINT_NAME  CONSTRAINT_TYPE TABLE_NAME  STATUS   INDEX_NAME 
---------------- --------------- ----------- -------- -----------
T1_U1            U               T1          ENABLED  T1_U1      
T1_U             U               T1          DISABLED

现在约束T1_U被禁用,现在不再需要强制执行索引的索引T1_U,并且 - 因为Oracle知道约束是由约束创建的而不是单独创建的(我不确定如何,但确实如此) - 它知道不再需要索引,因此可以删除它。 (您可以通过在创建约束之前先创建索引来确认这一点,并且当禁用约束时,索引仍然存在。)

ALTER INDEX T1_U1 RENAME TO T1_U;

SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');

OBJECT_NAME  OBJECT_TYPE        
------------ -------------------
T1_U         INDEX

select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');

CONSTRAINT_NAME  CONSTRAINT_TYPE TABLE_NAME  STATUS   INDEX_NAME 
---------------- --------------- ----------- -------- -----------
T1_U1            U               T1          ENABLED  T1_U       
T1_U             U               T1          DISABLED

因为不再有索引T1_U,我们可以将T1_U1索引重命名为T1_U。但请注意,这并不会改变与之关联的约束 - 它仍然属于T1_U1约束。

ALTER TABLE T1 DROP CONSTRAINT T1_U;

SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');

OBJECT_NAME  OBJECT_TYPE        
------------ -------------------
T1_U         INDEX     

select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');

CONSTRAINT_NAME  CONSTRAINT_TYPE TABLE_NAME  STATUS   INDEX_NAME 
---------------- --------------- ----------- -------- -----------
T1_U1            U               T1          ENABLED  T1_U

因此,当您删除不再具有关联索引的T1_U约束时,除了T1_U约束之外不会删除任何其他约束。重命名的T1_U索引属于T1_U1约束,因此,您不会期望它被删除。

此外,如果你现在试着这样做:

drop index t1_u;

你得到:

  

ORA-02429:无法删除用于强制执行唯一/主键的索引

希望这能为您解决第一个问题。

关于你的第二个问题 - "你可以告诉我有什么办法可以实现上述目标吗?"这完全取决于你想要做什么。希望我上面的解释能让你弄清楚你的例子中发生了什么,为什么,并让你回答你自己的问题。

如果还没有,请更新您的问题,并提供有关您尝试实现的内容的更多信息。