Oracle

不能刪除不存在的約束,也不能創建它

  • December 26, 2019

在使用生產數據副本測試一些遷移腳本(腳本在開發數據中執行良好)時,我發現了一個奇怪的情況。約束已更改,因此我發出 DROP + ADD 命令:

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
   CONTROL_ID,
   CALLE_AYTO_DUPL
)
ENABLE;

DROP 命令執行良好,但 ADD 命令失敗。現在,我陷入了一個惡性循環。我無法刪除約束,因為它不存在(初始刪除按預期工作):

ORA-02443: 無法刪除約束 - 不存在的約束

而且我無法創建它,因為名稱已經存在:

ORA-00955: 名稱已被現有對象使用

A_DUP_CALLE_UK1在 SQL Developer 的搜尋框中輸入內容,然後……就在那裡!所有者、表名、表景……一切都匹配:它不是同名的不同對象,它我原來的約束。該表出現在約束詳細資訊中,但約束未出現在表的詳細資訊中。

我的問題:

  • 對此有何解釋?
  • 當我在實時伺服器中進行真正的升級時,如何確保不會發生這種情況?

(伺服器是 10g XE,我沒有足夠的聲望來創建標籤。)

猜測我會說瑪麗安是對的,這是由具有相同名稱的唯一索引和約束引起的,例如:

create table t( k1 integer, k2 integer, 
               constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
               constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

通常,當您添加唯一約束時,會創建一個具有相同名稱的唯一索引 - 但索引和約束不是一回事。看看all_indexes是否有一個索引被呼叫A_DUP_CALLE_UK1,並在你刪除它之前嘗試弄清楚它是否被其他東西使用!

引用自:https://dba.stackexchange.com/questions/5332