从Oracle DB中查找ghost约束

时间:2010-03-03 14:44:15

标签: sql oracle unique-constraint ora-00001

我在表中有一个约束


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,因为它已经在几周前被删除了,我也无法在数据库中看到它。

2 个答案:

答案 0 :(得分:31)

您是否仍然拥有该约束使用的索引?因为除非在删除约束时包含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')
  2  /
insert into t23 values (1, 'MR KNOX')
*
ERROR at line 1:
ORA-00001: unique constraint (APC.T23_IDX) violated


SQL>

请注意错误消息中的细微更改。第二个失败引用索引名称,而原始消息引用约束。如果索引名称与约束名称相同,则很难诊断它。

如果没有显式预先创建唯一索引,Oracle的默认行为是创建一个非唯一索引。因此,在不删除索引的情况下删除约束不会导致此问题。 (请注意,这种行为适用于11g。我认为 - 但不能确定 - 它在早期版本中也是如此)。

答案 1 :(得分:1)

尝试检查此列的索引。在某些情况下,约束删除后不会删除与约束关联的索引