2015-11-02 129 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:不能刪除用於唯一/主鍵

執法指標

希望這會爲您解決第一個問題。

對於第二個問題 - 「請問我可以告訴我有什麼方法可以達到上述目的嗎?」它完全取決於你想要做什麼。希望我上面的解釋能夠讓你瞭解你的例子和原因,以及讓你回答你自己的問題。

如果還沒有,請更新您的問題,提供更多關於您想要達到的內容的信息。