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

16
задан OMG Ponies 25 April 2011 в 15:53
поделиться

2 ответа

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

32
ответ дан 30 November 2019 в 17:15
поделиться

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

1
ответ дан 30 November 2019 в 17:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: