Поиск ограничения призраков из Oracle DB

У меня было ограничение в таблице


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, поскольку он был удален уже несколько недель назад, и я не вижу его в базе данных.

Ответы

Ответ 1

У вас есть индекс, который использовался этим ограничением? Потому что, если вы не включили предложение 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 - это создание неидеального индекса. Следовательно, отказ от ограничения без снижения индекса не вызывает этой проблемы. (Предостерегайте, что это поведение относится к 11 г. Я полагаю, но не могу быть уверенным, что это также в предыдущих версиях).

Ответ 2

Попробуйте проверить индекс для этих столбцов. В некоторых случаях индекс, связанный с ограничением, не удаляется после удаления ограничения