sql – 从Oracle DB查找ghost约束

我在表中有一个约束
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的,我假定 – 但不能确定 – 在早期版本中也是这样).

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...