sim*_*mon 16 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")
)
/
Run Code Online (Sandbox Code Playgroud)
两周前我修改了表,添加了一些列,删除了约束"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.
Run Code Online (Sandbox Code Playgroud)
当我执行语句时
SELECT *
FROM user_cons_columns
WHERE constraint_name = 'PK_USERSAPPLICATIONS'
Run Code Online (Sandbox Code Playgroud)
我得零行.怎么可能?Oracle不应该知道约束PK_USERSAPPLICATIONS,因为它已经在几周前被删除了,我也无法在数据库中看到它.
APC*_*APC 32
你还有那个约束使用的索引吗?因为除非你DROP INDEX在删除约束时包含该子句,否则它仍将存在.从...开始
SELECT *
FROM user_indexes
WHERE index_name = 'PK_USERSAPPLICATIONS'
/
Run Code Online (Sandbox Code Playgroud)
或者,
select index_name
from user_indexes
where table_name = 'USERSAPPLICATIONS'
and uniqueness='UNIQUE'
/
Run Code Online (Sandbox Code Playgroud)
要么
select index_name
from user_ind_columns
where table_name = 'USERSAPPLICATIONS'
and column_name in ('USERID' ,'APPLICATIONNAME')
/
Run Code Online (Sandbox Code Playgroud)
编辑
概念证明
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>
Run Code Online (Sandbox Code Playgroud)
因此约束起作用.如果我们放弃它而没有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>
Run Code Online (Sandbox Code Playgroud)
请注意错误消息中的细微更改.第二个失败引用索引名称,而原始消息引用约束.如果索引名称与约束名称相同,则很难诊断它.
如果没有显式预创建唯一索引,Oracle的默认行为是创建非唯一索引.因此,在不删除索引的情况下删除约束不会导致此问题.(警告这种行为适用于11g.我认为 - 但不能确定 - 它在早期版本中也是这样).