Sql 从oracledb中查找ghost约束
我在一张桌子上有点拘束Sql 从oracledb中查找ghost约束,sql,oracle,unique-constraint,ora-00001,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_USERSAPPLICATIO
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_用户应用程序,因为它在几周前就已经被删除了,而且我在数据库中也看不到它。您还有该约束使用的索引吗?因为除非在删除约束时包含
DROP INDEX
子句,否则它仍将存在。从
SELECT *
FROM user_indexes
WHERE index_name = 'PK_USERSAPPLICATIONS'
/
或者
select index_name
from user_indexes
where table_name = 'USERSAPPLICATIONS'
and uniqueness='UNIQUE'
/
或
编辑
概念证明
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的这种行为是正确的。我推测——但不能确定——在早期版本中也是如此)。尝试检查此列的索引。在某些情况下,删除约束后与约束相关的索引不会被删除非常好且彻底的回答。就是这样-愚蠢的是,索引的命名与我的案例中的约束完全相同。谢谢。找到索引后,我使用另一个脚本drop index PK_USERSAPPLICATIONS删除它;谢谢你节省了我宝贵的时间。Oracle不应该使用至少是的名称添加类似IDX的内容,以便我们知道它的索引。我在使用SQL Developer时遇到过这种情况。奇怪的是,当我删除约束时,程序没有警告我。
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>