我在表中有一个约束
CREATE TABLE "USERSAPPLICATIONS" ( "USERID" NUMBER NOT NULL,"APPLICATIONNAME" VARCHAR2 (30) NOT NULL,CONSTRAINT "PK_USERSAPPLICATIONS" PRIMARY KEY ("USERID","APPLICATIONNAME") ) /
两周前我修改了表,添加了一些列,删除了约束“PK_USERSAPPLICATIONS”并添加了一个代理键.我可以在Oracle sql Developer中看到约束PK_USERSAPPLICATIONS不再存在.
无论如何,当我尝试添加具有相同userid / applicationName组合的两个条目时,我得到一个错误
sql Error: ORA-00001: unique constraint (ACCOUNTMP1.PK_USERSAPPLICATIONS) violated 00001. 00000 - "unique constraint (%s.%s) violated" *Cause: An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode,you may see this message if a duplicate entry exists at a different level. *Action: Either remove the unique restriction or do not insert the key.
当我执行该声明
SELECT * FROM user_cons_columns WHERE constraint_name = 'PK_USERSAPPLICATIONS'
我得到零行.怎么可能? Oracle不应该知道约束PK_USERSAPPLICATIONS,因为它已经在几周前被删除了,我也看不到它在数据库中.
解决方法
你还有那个约束使用的索引吗?因为除非您在删除约束时包含DROP INDEX子句,否则它将仍然存在.从…开始
SELECT * FROM user_indexes WHERE index_name = 'PK_USERSAPPLICATIONS' /
或者,
select index_name from user_indexes where table_name = 'USERSAPPLICATIONS' and uniqueness='UNIQUE' /
要么
select index_name from user_ind_columns where table_name = 'USERSAPPLICATIONS' and column_name in ('USERID','APPLICATIONNAME') /
编辑
概念证明
sql> create table t23 (id number not null,alt_key varchar2(10) not null) 2 / Table created. sql> create unique index t23_idx on t23 (id) 2 / Index created. sql> alter table t23 add constraint t23_pk primary key (id) using index 2 / Table altered. sql> insert into t23 values (1,'SAM I AM') 2 / 1 row created. sql> insert into t23 values (1,'MR KNOX') 2 / insert into t23 values (1,'MR KNOX') * ERROR at line 1: ORA-00001: unique constraint (APC.T23_PK) violated sql>
所以约束工作.如果我们删除它,没有DROP INDEX子句会发生什么?
sql> alter table t23 drop constraint t23_pk 2 / Table altered. sql> insert into t23 values (1,'MR KNOX') * ERROR at line 1: ORA-00001: unique constraint (APC.T23_IDX) violated sql>
注意错误消息中的微妙变化.第二个失败引用索引名称,而原始消息引用约束.如果索引名称与约束名称相同,则很难诊断这一点.
如果您没有明确预先创建唯一索引,则Oracle的默认行为是创建一个非唯一索引.因此,删除约束而不丢弃索引不会导致此问题. (请注意,这个行为是11g的,我假定 – 但不能确定 – 在早期版本中也是这样).