2011-09-27 12 views
12

테이블에 새 행을 만들려고합니다. 테이블에는 두 가지 제약 조건이 있습니다. 하나는 키 필드 (DB_ID)에, 다른 하나는 필드 ENV의 값 중 하나가되도록 제한합니다. 내가 삽입을 할 때, 나는 삽입하기 위해 노력하고있어 필드 중 하나로서 키 필드를 포함, 아직 나는이 오류 받고 있어요하지 않습니다 여기에삽입 중 고유 한 제약 조건 위반 : 이유가 무엇입니까? (Oracle)

unique constraint (N390.PK_DB_ID) violated 

하면 오류를 발생시키는 SQL의 :

insert into cmdb_db 
    (narrative_name, db_name, db_type, schema, node, env, server_id, state, path) 
values 
    ('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '') 

수동으로 행을 삽입 한 경우 오라클이 이미 사용중인 DB_ID를 할당하려고 시도했을 가능성이 있습니다. 이 데이터베이스의 데이터는 어떻게 든 프로덕션 데이터베이스에서 복원/이동되었지만 어떻게 수행되었는지에 대한 세부 정보는 없습니다.

의견이 있으십니까?

답변

34

아마도, 그 값은 테이블에 정의 된 삽입 트리거 전에 행 수준에 의해 채워되고있다. 이 트리거는 아마도 시퀀스에서 값을 선택합니다.

프로덕션 데이터베이스에서 데이터가 옮겨 졌으므로 (최근에는 아마도) 데이터를 복사 할 때 시퀀스도 수정되지 않았을 것입니다. 나는 시퀀스가 ​​현재 오류로 이어지는 테이블에있는 최대 DB_ID보다 훨씬 낮은 값을 생성하고 있다고 생각합니다.

내가 의심과 같이, 사용되는 순서를 결정하기 위해 트리거보고하고

SELECT <<sequence name>>.nextval 
    FROM dual 

을하고

SELECT MAX(db_id) 
    FROM cmdb_db 

만약에 저것을 비교하여 순서를이 의심을 확인할 수

데이터베이스에 이미 존재하는 값을 생성하는 경우 사용되지 않는 값을 생성 할 때까지 시퀀스를 증가 시키거나 INCREMENT을 매우 크게 설정하고 nextval을 한 번 가져 와서을 설정할 수 있습니다 210에서 1로 돌아 간다.

+9

+1 현명한 추측 – APC

1

기본 키 필드 DB_ID에 값을 제공하지 않는 것 같습니다. 이것이 기본 키인 경우 해당 열에 고유 한 값을 제공해야합니다. 이를 제공하지 않는 유일한 방법은 삽입시에 시퀀스에서 파생 된 값을 제공하는 데이터베이스 트리거를 만드는 것입니다.

다른 데이터베이스의 복원으로이 새 인스턴스에 시퀀스가있는 경우 값을 다시 사용하려고 시도했을 수 있습니다. 이전 데이터에 1 - 1000의 고유 키가 있고 현재 시퀀스의 값이 500 인 경우 이미 존재하는 값이 생성됩니다. 이 테이블에 대한 시퀀스가 ​​존재하고이를 사용하려고하면 테이블의 값을 시퀀스의 현재 값과 조정해야합니다.

당신은 (이 물론 존재하는 경우) 당신이 당신의 DB에 이미 존재하는 기본 키를 복제하는 것처럼

+0

데이터베이스에 대한 내 정보에 따르면 새 행을 삽입 할 때 키가 자동으로 생성되어야한다고 나와 있습니다. 이것이 내가 DB_ID에 값을 제공하지 않는 이유입니다. 또한이 같은 기술은 데이터베이스의 다른 테이블에서도 작동합니다. 자동으로 생성 된 ID 키가 있습니다. – Sean

+0

데이터 사전을 쿼리하여 새 환경에서 필요한 트리거/시퀀스가 ​​있는지 확인할 수 있습니까? 아마도 모든 것이 오래된 환경에서 가져온 것이 아닙니다. –

1

귀하의 오류가 보이는 시퀀스의 현재 값을 볼 수 SEQUENCE_NAME.CURRVAL를 사용할 수 있습니다. IDENTITY 키워드와 같은 것을 사용하여 자체 기본 키를 구현하도록 SQL 코드를 수정해야합니다. 당신이 DB_ID 컬럼에 대한 값을 제공하지 않는 때문에

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY, 
    ... 

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC), 

); 
+1

IDENTITY는 Oracle에서 유효한 키워드가 아닙니다. –

+0

오라클 –

+1

에 대한 유효하지 않은 문입니다. 선생님, 맞습니다. 내 솔루션은 Oracle이 아닌 SQL에서 작동합니다. 오라클에서 SQL의 Identity를 복제하고 싶다면 Sequence [link] (http://www.techonthenet.com/oracle/sequences.php)를 사용하고 싶을 것입니다. @Justin_Cave는 그의 답변에 훌륭한 구현을 가지고 있습니다. –

관련 문제