你可以有它由一個非唯一索引備份的唯一約束,如果你創建索引第一:
create table t42 (id number);
Table T42 created.
create index per_index on t42(id);
Index PER_INDEX created.
alter table t42 add constraint per_unique unique (id);
Table T42 altered.
select index_name, uniqueness
from user_indexes where table_name = 'T42';
INDEX_NAME UNIQUENES
------------------------------ ---------
PER_INDEX NONUNIQUE
select constraint_name, constraint_type, status, deferrable, index_name
from user_constraints where table_name = 'T42';
CONSTRAINT_NAME C STATUS DEFERRABLE INDEX_NAME
------------------------------ - -------- -------------- ------------------------------
PER_UNIQUE U ENABLED NOT DEFERRABLE PER_INDEX
賦予的名稱似乎有可能這是第一次,然後添加一個索引稍後將限制放在頂部。
在兩個步驟中做到這一點的一個原因是如果您知道現有數據不是唯一的,但您希望所有新數據都是唯一的;那麼你可以創建一個非唯一索引,並與novalidate
子句添加約束:
alter table t42 add constraint per_unique unique (id) novalidate;
當一個新的行添加非唯一索引仍然可以用來快速檢查是否已經有一個匹配條目,如果存在的話,約束可以拋出異常。對於該檢查,索引是否是唯一的並不重要。唯一真正的區別是檢查可能會獲得更多的現有匹配,但是約束只是關心它是否爲非零。
如果您使唯一約束可延遲,Oracle還會自動創建一個非唯一索引;具有唯一索引的異常會被拋出,立即爲檢查不能被推遲:
create table t42 (id number);
Table T42 created.
alter table t42 add constraint per_unique unique (id) deferrable;
Table T42 altered.
select index_name, uniqueness
from user_indexes where table_name = 'T42';
INDEX_NAME UNIQUENES
------------------------------ ---------
PER_UNIQUE NONUNIQUE
select constraint_name, constraint_type, status, deferrable, index_name
from user_constraints where table_name = 'T42';
CONSTRAINT_NAME C STATUS DEFERRABLE INDEX_NAME
------------------------------ - -------- -------------- ------------------------------
PER_UNIQUE U ENABLED DEFERRABLE PER_UNIQUE
注意約束不必具有相同的名稱作爲索引,如果你在兩個步驟創建它們 - 當您添加約束時,它將使用與約束所針對的列匹配的任何索引。當自動創建索引時,約束和索引具有相同的名稱。
不能裝載有違反約束,除非你將其刪除的數據,但它可能有一個原因,它是不是輕率地做。你需要理解爲什麼約束存在,以及爲什麼你的數據違反了它 - 其中一個可能是錯誤的,但我們不能真正幫你決定。這是一個商業決策,也是一個技術問題。
您可以發表您的表的完整DDL,或至少描述一下'PER_INDEX'嗎? – Aleksej
您可以擁有唯一的由非唯一索引支持的約束。 'user_indexes'和'user_constraints'爲你的表顯示什麼? –