Instrukcja ALTER TABLE powodowała konflikt z ograniczeniem FOREIGN KEY


201

Mam problem podczas próby dodania klucza obcego do mojej tblDomaretabeli; co ja tu robię źle?

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

Komunikat o błędzie:

Instrukcja ALTER TABLE powoduje konflikt z ograniczeniem FOREIGN KEY „FK_ tblDomare _PersN__5F7E2DAC”. Konflikt wystąpił w bazie danych „almu0004”, tabela „dbo.tblBana”, kolumna „BanNR”.

Odpowiedzi:


352

Wystąpiło to, ponieważ próbowano utworzyć klucz obcy od tblDomare.PersNRdo tblBana.BanNRale /, a wartości w tblDomare.PersNRnie pasują do żadnej z wartości w tblBana.BanNR. Nie możesz stworzyć relacji, która narusza integralność referencyjną.


91
To była odpowiedź dla mnie, ale wciąż walczyłem ze zrozumieniem, gdzie jest problem, więc dam przykład laika. Jeśli masz tabelę o nazwie „Zamówienia” i tabelę „Klienci” i usunąłeś niektórych starych klientów, ale nie ich zamówienia, ten błąd pojawi się, jeśli zdecydujesz się utworzyć klucz obcy z Zamówienia. .ID. Niektóre zamówienia nie mają już odpowiedniego klienta, więc nie można dodać klucza obcego.
Chad Hedgcock

10
Oto zapytanie do sprawdzenia nieprawidłowych wartości: wybierz odrębną referrerTable.referenceColumn z referrerTable left join referTable on referrerTable.referenceColumn = referrerTable.referenceColumn gdzie referrerTable.referenceColumn ma wartość null;
jumxozizi

6
W mgnieniu oka możesz również użyć opcji „ALTER TABLE tablename WITH NOCHECK ...”, aby dodać FK. Umożliwi to dodanie relacji, nawet jeśli istniejące dane łamią to ograniczenie. Oczywiście lepiej jest najpierw wyczyścić dane, ale przynajmniej daje to inną opcję.
DaveInMaine

2
@DaveInMaine Jeśli ktoś dezaktywuje ograniczenia bazy danych „kiedy jest to pożądane”, zapytałbym przede wszystkim, po co się nimi zajmować, a nie po prostu je pomijać, jeśli nie jest się zainteresowanym integralnością bazy danych.
Smutje

1
co za kiepski komunikat o błędzie. widziałem to wcześniej, ale całkowicie mnie zaskoczyło, że coś jest uszkodzone
Simon_Weaver

47

To zapytanie było dla mnie bardzo przydatne. Pokazuje wszystkie wartości, które nie mają żadnych dopasowań

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

Bardzo proste i niezwykle przydatne przy wyszukiwaniu błędnych wpisów. Wielkie dzięki!
TheMSG

wielkie dzięki! fajna odpowiedź, fajny dodatek
Egli Becerra

41

Wypróbuj to rozwiązanie:

W Twojej tabeli znajduje się element danych, którego powiązana wartość nie istnieje w tabeli, której chcesz użyć jako tabeli klucza podstawowego. Ustaw pustą tabelę lub dodaj skojarzoną wartość do drugiej tabeli.


1
To działa dla mnie ... dzięki
user3623037

29

Możliwe jest utworzenie klucza obcego przy użyciu polecenia ALTER TABLE nazwa tabeli WITH NOCHECK ..., co pozwoli na dane, które naruszają klucz obcy.

Opcja „ALTER TABLE tablename WITH NOCHECK ...”, aby dodać FK - To rozwiązanie zadziałało dla mnie.


18
Należy pamiętać, że zezwolenie na takie naruszenia jest sprzeczne z celem ograniczenia klucza obcego.
zreformowany

Niebezpieczny...!!! Powinien być używany tylko wtedy, gdy nie chcesz utracić danych znajdujących się obecnie w tabeli. Ale nawet wtedy, dlaczego nie wykonać kopii zapasowej, a następnie usunąć nieprawidłowe identyfikatory.
Andrei Bazanov

Aby to zrobić, muszę zaimplementować za pomocą java / spring / code, a nie bezpośrednio przez zapytanie SQL, wszelkie pomysły, jak to zrobić za pomocą następującego kodu: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) i zrobiłem to, rozwiązując za pomocą zapytania do bazy danych:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza,

12

Wydaje mi się, że wartość kolumny w tabeli kluczy obcych powinna być zgodna z wartością kolumny w tabeli kluczy podstawowych. Jeśli próbujemy utworzyć ograniczenie klucza obcego między dwiema tabelami, w których wartość w jednej kolumnie (będzie to klucz obcy) różni się od wartości kolumny tabeli kluczy podstawowych, to wyśle ​​komunikat.

Dlatego zawsze zaleca się wstawianie tylko tych wartości w kolumnie Klucz obcy, które są obecne w kolumnie tabeli kluczy podstawowych.

Na przykład. Jeśli kolumna Primary table ma wartości 1, 2, 3, aw kolumnie Foreign key wprowadzone wartości są różne, zapytanie nie zostanie wykonane, ponieważ oczekuje, że wartości będą znajdować się w przedziale od 1 do 3.


12

Przed dodaniem klucza obcego do tabeli wykonaj następujące czynności

  1. Upewnij się, że tabela musi być pusta lub Dane w kolumnie powinny być zgodne.
  2. Upewnij się, że nie jest zerowa.
  3. Jeśli tabela zawiera nie idź do projektowania i zmiany, zrób to ręcznie.

    zmień tabelę Tabela 1 dodaj odwołania do klucza obcego (Nazwa kolumny) Tabela 2 (Nazwa kolumny)

    alter table Tabela 1 alter column Atrybut nazwy kolumny nie jest pusty


11

Wyczyść dane z tabel, a następnie utwórz relacje między nimi.


Dziękuję max. zadziałało dla mnie, jeśli mają dane, nawet relacje są idealne, polecenie Update-Database nie zadziała.
robert jebakumar 2

Nie ma potrzeby usuwania żadnych danych, o ile są one ważne zgodnie z tworzonym kluczem obcym.
jumxozizi

8

Wypróbuj DELETEaktualne dane z tblDomare.PersNR. Ponieważ wartości w tblDomare.PersNRnie pasują do żadnej z wartości w tblBana.BanNR.


@agenc czy odpowiedziałem na twoje pytanie?
Thinker Bell,

3

Miałem również ten błąd, ponieważ odesłał Smutje upewnij się, że nie masz wartości w kolumnie klucza obcego w podstawowej tabeli kluczy obcych, której nie ma w tabeli referencyjnej, tj. (każda wartość w Twojej podstawowej tabeli kluczy obcych (wartość kolumny, która jest klucz obcy) musi również znajdować się w kolumnie tabeli referencyjnej) dobrze jest najpierw opróżnić podstawową tabelę kluczy obcych, a następnie ustawić klucze obce


2

dane wprowadzone do tabeli (tbldomare) nie pasują do danych, które przypisałeś do tabeli kluczy podstawowych. pisz między tbldomare i dodaj to słowo (z nocheck), a następnie wykonaj swój kod.

na przykład wpisałeś tabelę tbldomar te dane

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

i przypisałeś foreign keytabelę tylko do akceptacji 1,2,3.

masz dwa rozwiązania, jedno to usunięcie danych wprowadzonych do tabeli, a następnie wykonanie kodu. innym jest napisanie tego słowa (z nocheck), umieszczenie go między nazwą tabeli i dodanie w ten sposób

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

2

Dzieje się tak ze mną, ponieważ projektuję swoją bazę danych i zauważam, że zmieniam ziarno w mojej głównej tabeli, teraz tabela relacyjna nie ma klucza obcego na głównej tabeli.

Więc muszę obciąć obie tabele i teraz działa!


2

Powinieneś sprawdzić, czy twoje tabele zawierają jakieś dane w wierszach. Jeśli "tak", to powinieneś skrócić tabele lub możesz sprawić, by miały taką samą liczbę danych na tblDomare.PersNRto tblBana.BanNRi vise-verse.


2

Smutje ma rację, a Chad HedgeCock dał świetny przykład laika. Chciałbym skorzystać z przykładu Chada, oferując sposób na znalezienie / usunięcie tych rekordów. Będziemy używać Klienta jako Rodzica i Porządku jako dziecka. CustomerId jest polem wspólnym.

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

jeśli czytasz ten wątek ... otrzymasz wyniki. To są osierocone dzieci. wybierz * z Order Child left dołącz do Customer Parent na Child.CustomerId = Parent.CustomerId gdzie Parent.CustomerId ma wartość null. Zwróć uwagę na liczbę wierszy w prawym dolnym rogu.

Idź i sprawdź z kimkolwiek potrzebujesz, że zamierzasz usunąć te wiersze!

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

Uruchom pierwszy bit. Sprawdź, czy liczba wierszy jest zgodna z oczekiwaniami

popełnij tran

commit tran 

Bądź ostrożny. Czyjś niechlujny program wpędził cię w ten bałagan. Zanim usuniesz sieroty, upewnij się, że rozumiesz, dlaczego. Może trzeba przywrócić rodzica.


Dziękuję za odpowiedź. Gram z bazą danych stackoverflow (a właściwie gamedev) i znalazłem dwie wartości NULL, kiedy opuściłem Odznaki z użytkownikami. Nic dziwnego, że ograniczenia nie zadziałały ...
Nicholas Humphrey

2

W moim scenariuszu, używając EF, próbując utworzyć nowy klucz obcy na istniejących danych, błędnie próbowałem wypełnić dane (utworzyć łącza) PO utworzeniu klucza obcego.

Rozwiązaniem jest wypełnienie danych przed utworzeniem klucza obcego, ponieważ sprawdza je wszystkie, aby sprawdzić, czy linki są rzeczywiście prawidłowe. Więc prawdopodobnie nie zadziała, jeśli jeszcze go nie zapełnisz.


2

Najpierw usuń dane z tej tabeli, a następnie ponownie uruchom migrację. Osiągniesz sukces


2

Kiedy definiujesz klucz obcy w tabeli B odwołując się do klucza podstawowego tabeli A, oznacza to, że gdy wartość znajduje się w B, musi znajdować się w A. Ma to na celu zapobieżenie niespójnym modyfikacjom tabel.

W Twoim przykładzie Twoje tabele zawierają:

tblDomare z PRIMARY KEY (PersNR):

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

tblBana:

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

To oświadczenie:

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

mówi, że każda linia tblDomarez kluczem PersNRmusi mieć odpowiednik w tabeli tblBanana klucz BanNR. Twój błąd wynika z tego, że masz wstawione wiersze tblDomarebez odpowiednika tblBana.

2 sposoby rozwiązania problemu: - albo dodaj wiersze za tblBanapomocą BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines intblDomare that have no correspondance intblBana` (ale twoja tabela będzie pusta)

Porada ogólna : przed zapełnieniem tabel należy mieć ograniczenie klucza obcego. Klucze obce są tutaj, aby uniemożliwić użytkownikowi tabeli wypełnianie tabel niespójnościami.


1
„Twój błąd wynika z tego, że w tblDomare znajdują się wiersze, które nie mają odpowiednika w tblBana”. To było to!
mrkarp

1

W moim projekcie napotykam problem.

wprowadź opis obrazu tutaj

W tabeli podrzędnej nie ma żadnego rekordu o identyfikatorze równym 1 i 11

mag

Wstawiłem tabelę DEAL_ITEM_THIRD_PARTY_PO, której identyfikator jest równy 1 i 11, a następnie mogę utworzyć FK


-3

i po prostu do Twojej wiadomości, na wypadek, gdybyś sprawdził wszystkie swoje odniesienia do danych i nie znalazł żadnych złych danych ... najwyraźniej nie jest możliwe utworzenie ograniczenia klucza obcego między dwiema tabelami i polami, w których te pola są kluczem podstawowym w obu tabelach! Nie pytaj mnie, skąd to wiem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.