Câu lệnh ALTER TABLE đã xung đột với ràng buộc FOREIGN KEY


184

Tôi gặp vấn đề khi cố gắng thêm khóa ngoại vào tblDomarebảng của mình ; tôi làm gì sai ở đây?

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);

Thông báo lỗi:

Câu lệnh ALTER TABLE đã xung đột với ràng buộc FOREIGN KEY "FK_ tblDomare _PersN__5F7E2DAC". Xung đột xảy ra trong cơ sở dữ liệu "almu0004", bảng "dbo.tblBana", cột 'BanNR'.

Câu trả lời:


333

Điều này xảy ra do bạn đã cố tạo khóa ngoại từ tblDomare.PersNRđến tblBana.BanNRnhưng / và các giá trị trong tblDomare.PersNRkhông khớp với bất kỳ giá trị nào trong tblBana.BanNR. Bạn không thể tạo một mối quan hệ vi phạm tính toàn vẹn tham chiếu.


87
Đây là câu trả lời cho tôi, nhưng tôi vẫn đấu tranh để nhận ra vấn đề ở đâu, vì vậy tôi sẽ đưa ra ví dụ của một giáo dân. Nếu bạn có một bảng có tên 'Đơn hàng' và một bảng có tên 'Khách hàng' và bạn đã xóa một số khách hàng cũ, nhưng không phải đơn hàng của họ, bạn sẽ gặp lỗi này nếu bạn quyết định tạo một khóa ngoại từ Đơn hàng. Khách hàng cho Khách hàng .Tôi. Một số đơn đặt hàng không có khách hàng tương ứng nữa, vì vậy không thể thêm khóa ngoại.
Chad Hedgcock

10
Đây là một truy vấn để kiểm tra các giá trị không chính xác: chọn tham chiếu riêng biệtTable.referenceColumn từ tham chiếuTable tham gia bên trái được giới thiệu trên giới thiệuTableTable.referenceColumn = giới thiệuTable.referenceColumn trong đó giới thiệuTableTable
jumxozizi

6
Trong một vài trường hợp, bạn cũng có thể sử dụng tùy chọn "ALTER TABLE tab VỚI NOCHECK ..." để thêm FK. Điều này sẽ cho phép bạn thêm mối quan hệ, mặc dù dữ liệu hiện tại phá vỡ ràng buộc. Rõ ràng là tốt hơn để làm sạch dữ liệu của bạn trước tiên, nhưng điều này ít nhất cung cấp cho bạn một tùy chọn khác.
DaveInMaine

2
@DaveInMaine Nếu một người vô hiệu hóa các ràng buộc cơ sở dữ liệu "khi muốn", tôi sẽ hỏi tại sao lại gây rắc rối cho chính họ với họ ngay từ đầu và không chỉ đơn giản bỏ qua chúng nếu không quan tâm đến tính toàn vẹn của cơ sở dữ liệu.
Smutje

1
Thật là một thông báo lỗi tệ hại. nhìn thấy nó trước đây nhưng tôi hoàn toàn mất cảnh giác khi nghĩ rằng một cái gì đó đã bị hỏng
Simon_Weaver

42

Truy vấn này rất hữu ích cho tôi. Nó hiển thị tất cả các giá trị không có bất kỳ kết quả khớp nào

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

37

Hãy thử giải pháp này:

Có một mục dữ liệu trong bảng của bạn có giá trị liên quan không tồn tại trong bảng mà bạn muốn sử dụng làm bảng khóa chính. Làm cho bảng của bạn trống hoặc thêm giá trị liên quan vào bảng thứ hai.


29

Có thể tạo khóa ngoại bằng cách sử dụng tablen ALTER TABLE VỚI NOCHECK ..., điều này sẽ cho phép dữ liệu vi phạm khóa ngoại.

Tùy chọn "ALTER TABLE tab VỚI NOCHECK ..." để thêm FK - Giải pháp này hiệu quả với tôi.


17
Xin lưu ý rằng việc cho phép các vi phạm như vậy đánh bại mục đích của ràng buộc khóa ngoại.
cải cách

Nguy hiểm...!!! Chỉ nên được sử dụng nếu bạn không muốn mất dữ liệu hiện tại trong bảng. Nhưng ngay cả sau đó, tại sao không thực hiện sao lưu và sau đó xóa Id không hợp lệ.
Andrei Bazanov

Tôi cần triển khai thông qua java / spring / code để thực hiện điều đó, không phải trực tiếp qua truy vấn SQL, bất kỳ ideia nào làm thế nào với mã sau đây: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) và tôi đã làm điều này để giải quyết thông qua truy vấn cơ sở dữ liệu:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza

11

Tôi đoán, một giá trị cột trong bảng khóa ngoại phải khớp với giá trị cột của bảng khóa chính. Nếu chúng ta đang cố gắng tạo một ràng buộc khóa ngoài giữa hai bảng trong đó giá trị bên trong một cột (sẽ là khóa ngoại) khác với giá trị cột của bảng khóa chính thì nó sẽ ném thông báo.

Vì vậy, luôn luôn chỉ nên chèn các giá trị đó vào cột Khóa ngoài có trong cột bảng Chính.

Dành cho người cũ Nếu cột bảng Chính có các giá trị 1, 2, 3 và trong cột Khóa ngoài, các giá trị được chèn là khác nhau, thì truy vấn sẽ không được thực thi vì nó dự kiến ​​các giá trị nằm trong khoảng 1 & 3.


11

Trước khi bạn thêm khóa ngoại vào bảng, hãy làm như sau

  1. Đảm bảo bảng phải trống hoặc Dữ liệu cột phải khớp.
  2. Hãy chắc chắn rằng nó không null.
  3. Nếu bảng chứa không đi đến thiết kế và thay đổi, hãy làm thủ công.

    thay đổi bảng Bảng 1 thêm tham chiếu khóa ngoài (Tên cột) Bảng 2 (Tên cột)

    bảng thay đổi Bảng 1 thay đổi cột Thuộc tính tên cột không null


10

Làm sạch dữ liệu của bạn khỏi các bảng của bạn và sau đó tạo mối quan hệ giữa chúng.


Cảm ơn bạn, tối đa. nó hoạt động với tôi nếu họ có dữ liệu ngay cả các mối quan hệ là hoàn hảo, lệnh Update-Database sẽ không hoạt động.
robert jebakumar2

Không cần thiết phải xóa bất kỳ dữ liệu nào miễn là chúng hợp lệ theo khóa ngoại được tạo.
jumxozizi

7

Hãy thử DELETEcác dữ liệu hiện tại từ tblDomare.PersNR. Bởi vì các giá trị tblDomare.PersNRkhông khớp với bất kỳ giá trị nào trong tblBana.BanNR.


@agenc tôi đã trả lời câu hỏi của bạn?
Nhà tư tưởng Bell

3

tôi cũng gặp lỗi này vì Smutje đã đảm bảo rằng bạn không có giá trị trong cột khóa ngoài của bảng khóa ngoại cơ sở không có trong bảng tham chiếu của bạn tức là (mọi giá trị trong bảng khóa ngoài cơ sở của bạn (giá trị của một cột khóa ngoại) cũng phải nằm trong cột bảng tham chiếu của bạn) trước hết hãy làm trống bảng khóa ngoại cơ sở của bạn sau đó đặt khóa ngoại


2

dữ liệu bạn đã nhập vào bảng (tbldomare) không khớp với dữ liệu bạn đã gán bảng khóa chính. viết giữa tbldomare và thêm từ này (không có kiểm tra) sau đó thực thi mã của bạn.

ví dụ: bạn đã nhập một bảng tbldomar dữ liệu này

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

và bạn đã chỉ định một foreign keybảng để chấp nhận 1,2,3.

bạn có hai giải pháp một là xóa dữ liệu bạn đã nhập vào một bảng sau đó thực thi mã. khác là viết từ này (không có kiểm tra) đặt nó giữa tên bảng của bạn và thêm như thế này

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

2

Điều này xảy ra với tôi, vì tôi đang thiết kế cơ sở dữ liệu của mình, tôi nhận thấy rằng tôi thay đổi hạt giống của mình trên bàn chính, bây giờ bảng quan hệ không có khóa ngoại trên bảng chính.

Vì vậy, tôi cần phải cắt bớt cả hai bảng, và bây giờ nó hoạt động!


2

Bạn sẽ thấy nếu các bảng của bạn có bất kỳ dữ liệu nào trên các hàng. Nếu "có" thì bạn nên cắt ngắn bảng (s) hoặc nếu không bạn có thể làm cho họ có cùng một số dữ liệu ở tblDomare.PersNRđến tblBana.BanNRvà vise-verse.


2

Smutje là chính xác và Chad HedgeCock đã đưa ra một ví dụ tuyệt vời của giáo dân. Id muốn xây dựng theo ví dụ của Chad bằng cách cung cấp cách tìm / xóa các bản ghi đó. Chúng tôi sẽ sử dụng Khách hàng làm Phụ huynh và Đặt hàng khi còn nhỏ. Khách hàng là lĩnh vực chung.

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

nếu bạn đang đọc chủ đề này ... bạn sẽ nhận được kết quả. Đây là những đứa trẻ mồ côi. chọn * từ thứ tự Trẻ trái tham gia Parent Parent trên Child.CustomerId = Parent.CustomerId trong đó Parent.CustomerId là null Lưu ý số hàng ở dưới cùng bên phải.

Đi xác minh với bất kỳ ai bạn cần để xóa những hàng này!

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

Chạy bit đầu tiên. Kiểm tra số hàng đó = những gì bạn mong đợi

cam kết

commit tran 

Hãy cẩn thận. Lập trình cẩu thả của ai đó đã đưa bạn vào mớ hỗn độn này. Hãy chắc chắn rằng bạn hiểu lý do tại sao trước khi bạn xóa trẻ mồ côi. Có lẽ cha mẹ cần được khôi phục.


Cảm ơn vi đa trả lơi. Tôi đang chơi với cơ sở dữ liệu stackoverflow (gamedev thực sự) và tìm thấy hai NULL khi tôi TRÁI phù hiệu với người dùng. Không có gì ngạc nhiên khi các ràng buộc không hoạt động ...
Nicholas Humphrey

1

Trong kịch bản của tôi, bằng cách sử dụng EF, khi cố gắng tạo Khóa ngoại mới này trên dữ liệu hiện có, tôi đã cố gắng điền dữ liệu (tạo liên kết) SAU khi tạo khóa ngoại.

Cách khắc phục là điền dữ liệu của bạn trước khi tạo khóa ngoại vì nó kiểm tra tất cả chúng để xem các liên kết có thực sự hợp lệ hay không. Vì vậy, nó không thể hoạt động nếu bạn chưa nhập cư.


1

Tôi gặp một số vấn đề trong dự án của tôi.

nhập mô tả hình ảnh ở đây

Trong bảng con, không có bất kỳ Id bản ghi nào bằng 1 và 11

pháp sư

Tôi đã chèn bảng DEAL_ITEM_THIRD_PARTY_PO mà Id bằng 1 và 11 thì tôi có thể tạo FK


0

Trước tiên, hãy xóa dữ liệu khỏi bảng đó và sau đó chạy lại di chuyển. Bạn sẽ có được thành công


0

Khi bạn xác định Khóa ngoài trong bảng B tham chiếu Khóa chính của bảng A, điều đó có nghĩa là khi một giá trị nằm trong B, thì nó phải ở A. Điều này là để ngăn chặn các sửa đổi không liên quan đến các bảng.

Trong ví dụ của bạn, các bảng của bạn chứa:

tblDomare với PRIMARY KEY (PersNR):

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

tblBana:

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

Tuyên bố này:

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

nói rằng bất kỳ dòng nào trong tblDomarekhóa PersNRphải có sự tương ứng trong bảng tblBanatrên khóa BanNR. Lỗi của bạn là do bạn có các dòng được chèn vào tblDomaremà không có sự tương ứng tblBana.

2 giải pháp để khắc phục sự cố của bạn: - thêm dòng vào tblBanabằng BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines intblDomare that have no correspondance intblBana` (nhưng bảng của bạn sẽ trống)

Lời khuyên chung : bạn nên có ràng buộc Khóa ngoài trước khi điền vào bảng. Các khóa ngoại có ở đây để ngăn người dùng của bảng điền vào các bảng không nhất quán.


-3

và chỉ FYI, trong trường hợp bạn thực hiện tất cả các kiểm tra tham chiếu dữ liệu của mình và không tìm thấy dữ liệu xấu ... rõ ràng không thể tạo ràng buộc khóa ngoài giữa hai bảng và các trường trong đó các trường đó là khóa chính trong cả hai bảng! Đừng hỏi tôi làm thế nào tôi biết điều này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.