존재하지 않는 구속 조건을 삭제할 수 없으며 작성할 수 없습니다.


16

프로덕션 데이터 사본으로 일부 마이그레이션 스크립트를 테스트하는 동안 (스크립트는 개발 데이터에서 제대로 실행 됨) 흥미로운 상황을 발견했습니다. 제약 조건이 변경되어 DROP + ADD 명령을 발행합니다.

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
    CONTROL_ID,
    CALLE_AYTO_DUPL
)
ENABLE;

DROP 명령은 제대로 작동했지만 ADD 명령은 실패했습니다. 이제 나는 악순환에 빠졌습니다. 제약 조건이 없기 때문에 제약 조건을 삭제할 수 없습니다 (초기 드롭이 예상대로 작동했습니다).

ORA-02443 : 제약을 드롭 할 수 없습니다-존재하지 않는 제약

이름이 이미 있기 때문에 만들 수 없습니다.

ORA-00955 : 기존의 오브젝트가 이미 사용하고있는 이름

A_DUP_CALLE_UK1SQL Developer의 검색 상자에 입력 하면 ...입니다! 소유자, 테이블 이름, tablescape ... 모든 경기 : 그것은 같은 이름의 다른 개체가 아닙니다, 그것은 이다 내 원래 제약. 테이블이 제한 조건 세부 사항에 나타나지만 제한 조건이 테이블의 세부 사항에 나타나지 않습니다.

내 질문 :

  • 이에 대한 설명은 무엇입니까?
  • 라이브 서버에서 실제 업그레이드를 수행 할 때 발생하지 않도록하려면 어떻게해야합니까?

(서버는 10g XE이며 태그를 생성 할만큼 평판이 부족합니다.)


아마도 다른 유형의 객체로 만들어졌으며 고유 한 제약 조건이 아닌 것일 수 있습니다. 아마 유일한 색인 ..
마리안

초기 작성이 테이블 이름 주위에 따옴표로 실행될 수 있습니까? 이름이 대소 문자를 구분합니다. 그렇다면 따옴표와 같은 경우에 빠질 수 있습니다.
Adam Butler

답변:


13

추측에 따르면 Marian이 옳고 같은 이름을 가진 고유 색인 및 제약 조건으로 인해 발생합니다.

create table t( k1 integer, k2 integer, 
                constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
                constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

일반적으로 고유 제한 조건을 추가하면 동일한 이름의 고유 색인이 작성되지만 색인과 제한 조건은 동일하지 않습니다. 에서보세요 all_indexes라는 인덱스가 있는지 A_DUP_CALLE_UK1당신이 그것을 드롭하기 전에이 뭔가에 의해 사용되는 경우에서 시도하고 그림!


이것이 문제였습니다. exp명령으로 생성 된 덤프 파일 에는 CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...원래 스크립트 세트에없는 명령문이 포함되어 있습니다 .
Álvaro González

6

매우 이상해 보인다.

당신은 실행할 수 있습니다 :

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

오라클이 어떤 종류의 객체에 대해 불평하는지 확인합니다. 그런 다음 해당 DROP 문을 실행할 수 있습니다.

내가 생각할 수있는 유일한 다른 것은 DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS해당 테이블에 속한 모든 것을 제거하고 완전히 다시 만드는 데 사용하는 테이블을 완전히 삭제하는 것입니다.

테이블에 유용한 데이터가 포함 된 경우 다음을 수행하기 전에 백업 할 수 있습니다.

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

테이블을 다시 만든 후에는 할 수 있습니다

INSERT INTO A_DUP_CALLE (col1, col2, col3) 
SELECT col1, col2, col3
FROM old_data

데이터를 복원합니다.


4

몇 분 전에 같은 문제가 있었는데 설명을 찾았습니다.

Oracle은 기본 키를 생성하여 제약 조건과 "UNIQUE"부분을 제어하는 ​​인덱스라는 두 가지 객체를 만듭니다.

제약 조건을 삭제하면 동일한 이름의 인덱스를 사용하여 인덱스가 그대로 유지되므로

alter table t drop constraint u1;

구속 조건 만 삭제합니다. 인덱스를 삭제하려면 다음을 실행해야합니다.

drop index u1;

이것은 일을해야합니다. 또는 명령을 사용하여 두 명령을 동시에 수행 할 수 있습니다

alter table t drop constraint u1 including indexes;

어느 db? 를 포함하여 오라클에서 작동하지 않습니다
Derick

1

기본 키 제약 조건에는 인덱스가 있습니다. 제약 조건은 삭제하지만 색인은 삭제하지 않습니다. 검사:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

당신은 볼 OBJECT_TYPEIS를 INDEX.

두 가지 모두를 수행하십시오.

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

이 작업을 수행

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

작동합니다.

영상: 여기에 이미지 설명을 입력하십시오


아니요 작동하지 않습니다. 귀하의 진술은 질문의 첫 번째 진술과 정확히 동일합니다.ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name 11

실제로 작동했습니다. 오늘 정오부터 같은 문제가 발생하여 해결책을 찾았습니다. 경우에 따라 CONSTRAINTS는 대소 문자를 구분하여 작성되었을 수 있으며,이 경우 구속 조건 이름을 큰 따옴표로 묶어야 합니다.
Sachin

그리고 그것은 나를 위해 일했습니다. 나는 제약 조건을 명시 적으로 지정하지 않았으므로 시스템은 자체 생성 된 이름 을 부여 Relationship142했으며 다른 NOT NULL제약 조건에는 name이 부여되었습니다 SYS_C0015910. 따라서 SYS_C0015910간단한 ALTER 쿼리로 성공적으로 삭제되었지만 DOUBLE QUOTESRelationship142
Sachin이

1
당신이 만든 예를 들어, 큰 따옴표를 사용하여 제약 : alter table ... add constraint "Relationship143" ... "Relationship143"참이 아닌 다른 이름입니다 RELATIONSHIP143. 그러나 "RELATIONSHIP143"하고 RELATIONSHIP143있는 동일
a_horse_with_no_name

2
Oracle (데이터베이스)은 자체적 으로 이름을 만들지 않습니다"Relationship143" . 이 작업을 수행 한 도구 중 하나 일 것입니다. 어쨌든 : 원래 질문의 맥락에서 귀하의 대답은 단순히 잘못되었습니다.
a_horse_with_no_name
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.