2015-11-02 128 views
0

我有一个表和2个约束 - 其中一个约束很平凡,我想从现有的表中删除它 - 它有数据。Oracle唯一约束删除和修改

所以下面是表 -

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个约束可以看出via--

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

现在下面是其中我下面

  1. 禁用T1_U步骤constraint--

    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;

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

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

  1. 然后,我试着修改T1_U - 它按预期失败了。

问题:你能告诉我有什么方法可以达到上述目的吗?

谢谢。

回答

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:不能删除用于唯一/主键

执法指标

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

对于第二个问题 - “请问我可以告诉我有什么方法可以达到上述目的吗?”它完全取决于你想要做什么。希望我上面的解释能够让你了解你的例子和原因,以及让你回答你自己的问题。

如果还没有,请更新您的问题,提供更多关于您想要达到的内容的信息。