ALTER TABLE 문이 FOREIGN KEY 제한 조건과 충돌했습니다.


184

tblDomare테이블에 외래 키를 추가하려고 할 때 문제가 있습니다 . 내가 여기서 뭘 잘못하고 있니?

CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);

CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));

INSERT INTO tblBana (BanNR)
Values (1);

INSERT INTO tblBana (BanNR)
Values (2);

INSERT INTO tblBana (BanNR)
Values (3);

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

에러 메시지:

ALTER TABLE 문이 FOREIGN KEY 제한 조건 "FK_ tblDomare _PersN__5F7E2DAC" 와 충돌했습니다 . 데이터베이스 "almu0004", 테이블 "dbo.tblBana", 열 'BanNR'에서 충돌이 발생했습니다.

답변:


333

당신이에서 외래 키 만들려고 때문에 발생 tblDomare.PersNRtblBana.BanNR있지만 /와의 값 tblDomare.PersNR의 값 중 하나와 일치하지 않습니다를 tblBana.BanNR. 참조 무결성을 위반하는 관계를 작성할 수 없습니다.


87
이것이 저에게 답이되었지만 여전히 문제가 어디에 있는지 깨닫는 데 어려움을 겪었습니다. 그래서 평신도의 모범을 보여 드리겠습니다. '주문'이라는 이름의 테이블과 '고객'이라는 이름의 테이블이 있고 이전 고객을 삭제했지만 해당 주문을 삭제하지 않은 경우 Orders.CustomerId에서 Customers로 외래 키를 만들면이 오류가 발생합니다. .신분증. 일부 주문에는 더 이상 해당 고객이 없으므로 외래 키를 추가 할 수 없습니다.
채드 헤지 콕

10
잘못된 값을 확인하는 쿼리는 다음과 같습니다. referrerTable 왼쪽 조인 referenceTable에서 distinct referrerTable.referenceColumn을 선택하십시오. referTable.referenceColumn = referrerTable.referenceColumn의 referenceTable은 referenceTable.referenceColumn이 널입니다.
jumxozizi

6
핀치에서 "ALTER TABLE tablename WITH NOCHECK ..."옵션을 사용하여 FK를 추가 할 수도 있습니다. 기존 데이터가 제한 조건을 위반하더라도 관계를 추가 할 수 있습니다. 데이터를 먼저 정리하는 것이 더 좋지만 적어도 다른 옵션이 제공됩니다.
DaveInMaine

2
@DaveInMaine 데이터베이스 제약 조건을 "필요할 때"비활성화하는 경우, 데이터베이스 무결성에 관심이없는 경우 처음에는 문제를 해결하고 단순히 건너 뛰지 않는 이유를 묻습니다.
Smutje

1
정말 오류 메시지입니다. 전에 그것을 보았지만 지금 막 무언가
잘못

42

이 쿼리는 나에게 매우 유용했습니다. 일치하지 않는 모든 값을 표시합니다

select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)

37

이 솔루션을 사용해보십시오 :

테이블에 관련 값이 기본 키 테이블로 사용하려는 테이블에 존재하지 않는 데이터 항목이 있습니다. 테이블을 비우거나 관련 값을 두 번째 테이블에 추가하십시오.


29

ALTER TABLE tablename WITH NOCHECK ...을 사용하여 외래 키를 만들 수 있습니다. 외래 키를 위반하는 데이터가 허용됩니다.

FK를 추가하기위한 "ALTER TABLE tablename WITH NOCHECK ..."옵션-이 솔루션은 저에게 효과적이었습니다.


17
이러한 위반을 허용하면 외래 키 제약 조건의 목적이 무효화됩니다.
개혁

위험한...!!! 현재 테이블에있는 데이터를 풀지 않으려는 경우에만 사용해야합니다. 그럼에도 불구하고 백업을 수행 한 다음 잘못된 ID를 제거하십시오.
안드레이 바자 노프

다음 코드를 사용하여이를 수행하는 방법을 SQL 쿼리를 통해 직접 수행하지 않고 java / spring / code를 통해 구현해야합니다. @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) 데이터베이스 쿼리를 통해이를 해결했습니다.alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza

11

외래 키 테이블의 열 값이 기본 키 테이블의 열 값과 일치해야합니다. 하나의 열 내부의 값 (외래 키로 이동)이 기본 키 테이블의 열 값과 다른 두 테이블 사이에 외래 키 제약 조건을 만들려고하면 메시지가 throw됩니다.

따라서 항상 기본 키 테이블 열에있는 외래 키 열에 해당 값만 삽입하는 것이 좋습니다.

예를 들어. 기본 테이블 열의 값이 1, 2, 3이고 외래 키 열의 경우 삽입 된 값이 다르면 값이 1과 3 사이 일 것으로 예상되므로 쿼리가 실행되지 않습니다.


11

테이블에 외래 키를 추가하기 전에 다음을 수행하십시오.

  1. 테이블이 비어 있거나 열 데이터가 일치해야합니다.
  2. 널이 아닌지 확인하십시오.
  3. 테이블에 디자인 및 변경이없는 경우 수동으로 수행하십시오.

    테이블 변경 표 1 외래 키 추가 (열 이름) 참조 표 2 (열 이름)

    alter table 표 1 alter column 열 이름 특성 not null


10

테이블에서 데이터를 정리 한 다음 관계를 맺습니다.


감사합니다, 최대 데이터가 있으면 관계가 완벽하더라도 Update-Database 명령이 작동하지 않습니다.
robert jebakumar2

생성되는 외래 키에 따라 데이터가 유효한 한 데이터를 제거 할 필요는 없습니다.
jumxozizi

7

DELETE의 현재 데이터를 사용해보십시오 tblDomare.PersNR. 의 값이의 값 tblDomare.PersNR과 일치하지 않기 때문입니다 tblBana.BanNR.


@agenc 질문에 대답 했습니까?
사상가 벨

3

Smutje가 언급 한대로이 오류가 발생했습니다. 참조 테이블에없는 기본 외래 키 테이블의 외래 키 열에 값이 없는지 확인하십시오 (예 : 기본 외래 키 테이블의 모든 값 (열의 값) 외래 키) 참조 테이블 열에 있어야합니다.) 기본 외래 키 테이블을 비운 다음 외래 키를 설정하는 것이 좋습니다.


2

테이블 (tbldomare)에 입력 한 데이터가 기본 키 테이블에 할당 한 데이터와 일치하지 않습니다. tbldomare 사이에 쓰고이 단어를 추가하고 (nocheck와 함께) 코드를 실행하십시오.

예를 들어이 데이터를 tbldomar 테이블에 입력했습니다.

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

그리고 당신 foreign key은 단지 수락 테이블을 할당했습니다 1,2,3.

두 가지 해결책 중 하나는 테이블에 입력 한 데이터를 삭제 한 다음 코드를 실행하는 것입니다. 다른 사람은이 단어를 작성합니다 (nocheck 사용)

ALTER TABLE  tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

2

데이터베이스를 설계하고 있기 때문에 주 테이블에서 시드를 변경하는 것을 알았습니다. 이제 관계형 테이블에는 주 테이블에 외래 키가 없습니다.

따라서 두 테이블을 모두 잘라야하며 이제 작동합니다!


2

테이블에 행에 대한 데이터가 있는지 확인해야합니다. 만약 "예"다음 테이블 (들)을 절단해야하거나 다른 당신이 그들에 동일한 데이터 수를 가질 수 tblDomare.PersNRtblBana.BanNR및 바이스 구절.


2

Smutje는 정확하고 Chad HedgeCock은 훌륭한 평신도의 모범을 제시했습니다. Id는 해당 레코드를 찾거나 삭제하는 방법을 제공하여 Chad의 예를 기반으로합니다. 고객을 부모로 사용하고 주문을 자녀로 사용합니다. CustomerId는 공통 필드입니다.

select * from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

이 글을 읽고 있다면 ... 결과를 얻을 수 있습니다. 이들은 고아입니다. 하위 항목에서 *를 선택하십시오. Child.CustomerId = Parent.CustomerId에서 Customer Parent에 참여하십시오.

이 행을 삭제하려는 사람이 누구인지 확인하십시오!

begin tran 
delete Order
from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

첫 번째 비트를 실행하십시오. 그 행 수를 확인하십시오 = 예상 한 것

트란을 저 지르다

commit tran 

조심해. 누군가의 조잡한 프로그래밍이 당신을이 혼란에 빠뜨 렸습니다. 고아를 삭제하기 전에 이유를 이해해야합니다. 부모를 회복해야 할 수도 있습니다.


답장을 보내 주셔서 감사합니다. 나는 stackoverflow 데이터베이스 (실제로 gamedev)로 놀고 있는데 사용자와 배지를 남길 때 두 개의 NULL을 발견했습니다. 제약 조건이 효과가 없었던 것은 당연합니다 ...
Nicholas Humphrey

1

내 시나리오에서 EF를 사용하여 기존 데이터 에서이 새로운 외래 키를 만들려고 할 때 외래 키를 만든 후 데이터를 채우려 고하지 않습니다 (링크 만들기).

수정은 외래 키가 링크가 실제로 유효한지 확인하기 위해 외래 키를 만들기 전에 데이터를 채우는 것입니다. 아직 채워 넣지 않으면 작동하지 않을 수 있습니다.


1

프로젝트에 문제가 있습니다.

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

자식 테이블에 ID가 1과 11 인 레코드가 없습니다.

마술사

ID가 1과 11 인 DEAL_ITEM_THIRD_PARTY_PO 테이블을 삽입 한 다음 FK를 생성 할 수 있습니다.


0

먼저 해당 테이블에서 데이터를 삭제 한 다음 마이그레이션을 다시 실행하십시오. 당신은 성공을 얻을 것이다


0

테이블 A의 기본 키를 참조하는 테이블 B에서 외래 키를 정의 할 때 값이 B에 있으면 A에 있어야 함을 의미합니다. 이는 테이블에 대한 일관성없는 수정을 방지하기위한 것입니다.

귀하의 예에서 테이블에는 다음이 포함됩니다.

tblDomare와 함께 PRIMARY KEY (PersNR):

PersNR     |fNamn     |eNamn      |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt'   |'Carlberg' |10
7606091347 |'Josefin' |'Backman'  |4
8508284163 |'Johanna' |'Backman'  |1
---------------------------------------------

바나나 :

BanNR
-----
1
2
3
-----

이 진술 :

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

tblDomarekey와 함께 입력 하는 모든 행은 key on PersNRtable tblBana에 해당해야합니다 BanNR. 에 tblDomare대응하지 않고 줄을 삽입했기 때문에 오류가 발생 했습니다 tblBana.

문제를 해결하기위한 2 가지 해결책 : -tblDomare 를 사용 tblBana하여 줄 추가BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines inthat have no correspondance in tblBana` (하지만 테이블이 비어있을 것입니다)

일반적인 조언 : 테이블을 채우기 전에 외래 키 제약 조건이 있어야합니다. 외래 키는 테이블 사용자가 불일치로 테이블을 채우지 못하도록하기위한 것입니다.


-3

참고로 모든 데이터 참조 검사를 수행하고 불량 데이터를 찾지 못한 경우 두 테이블과 필드 사이에 외래 키 제약 조건을 만들 수는 없습니다. 내가 이것을 어떻게 아는지 묻지 마십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.