Die Anweisung ALTER TABLE stand in Konflikt mit der Einschränkung FOREIGN KEY


184

Ich habe ein Problem beim Versuch, meiner tblDomareTabelle einen Fremdschlüssel hinzuzufügen . Was mache ich hier falsch?

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

Fehlermeldung:

Die Anweisung ALTER TABLE stand in Konflikt mit der FOREIGN KEY-Einschränkung " FK_tblDomare _PersN__5F7E2DAC". Der Konflikt trat in der Datenbank "almu0004", Tabelle "dbo.tblBana", Spalte "BanNR" auf.

Antworten:


333

Es ist aufgetreten, weil Sie versucht haben, einen Fremdschlüssel von tblDomare.PersNRbis zu erstellen , tblBana.BanNRaber / und die Werte in tblDomare.PersNRmit keinem der Werte in übereinstimmten tblBana.BanNR. Sie können keine Beziehung erstellen, die die referenzielle Integrität verletzt.


87
Dies war die Antwort für mich, aber ich hatte immer noch Probleme zu erkennen, wo das Problem lag, also werde ich ein Beispiel für einen Laien geben. Wenn Sie eine Tabelle mit dem Namen "Bestellungen" und eine Tabelle mit dem Namen "Kunden" haben und einige alte Kunden gelöscht haben, jedoch nicht deren Bestellungen, wird diese Fehlermeldung angezeigt, wenn Sie einen Fremdschlüssel aus "Orders.CustomerId" an "Kunden" senden .Ich würde. Einige Bestellungen haben keinen entsprechenden Kunden mehr, daher ist es unmöglich, den Fremdschlüssel hinzuzufügen.
Chad Hedgcock

10
Hier ist eine Abfrage, um die falschen Werte zu überprüfen: Wählen Sie eine eindeutige referrerTable.referenceColumn aus referrerTable aus.
Jumxozizi

6
Zur Not können Sie auch die Option "Tabellenname ALTER TABLE WITH NOCHECK ..." verwenden, um die FK hinzuzufügen. Auf diese Weise können Sie die Beziehung hinzufügen, obwohl vorhandene Daten die Einschränkung aufheben. Es ist natürlich besser, zuerst Ihre Daten zu bereinigen, aber dies gibt Ihnen zumindest eine andere Option.
DaveInMaine

2
@DaveInMaine Wenn man Datenbankeinschränkungen "wenn gewünscht" deaktiviert, würde ich fragen, warum man sich überhaupt mit ihnen befasst und sie nicht einfach überspringt, wenn man nicht an Datenbankintegrität interessiert ist.
Smutje

1
Was für eine miese Fehlermeldung. Ich habe es schon einmal gesehen, habe mich aber völlig
überrascht

42

Diese Abfrage war sehr nützlich für mich. Es werden alle Werte angezeigt, die keine Übereinstimmungen haben

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

37

Versuchen Sie diese Lösung:

In Ihrer Tabelle befindet sich ein Datenelement, dessen zugehöriger Wert in der Tabelle, die Sie als Primärschlüsseltabelle verwenden möchten, nicht vorhanden ist. Machen Sie Ihre Tabelle leer oder fügen Sie den zugehörigen Wert zur zweiten Tabelle hinzu.


29

Es ist möglich, den Fremdschlüssel mit dem Tabellennamen ALTER TABLE WITH NOCHECK ... zu erstellen, wodurch Daten zugelassen werden, die gegen den Fremdschlüssel verstoßen.

Option "ALTER TABLE tablename WITH NOCHECK ..." zum Hinzufügen des FK - Diese Lösung hat bei mir funktioniert.


17
Beachten Sie, dass das Zulassen solcher Verstöße den Zweck der Fremdschlüsseleinschränkung zunichte macht.
reformiert

Gefährlich...!!! Sollte nur verwendet werden, wenn Sie die aktuell in der Tabelle enthaltenen Daten nicht verlieren möchten. Aber selbst dann, warum nicht ein Backup machen und dann ungültige IDs entfernen.
Andrei Bazanov

Ich muss über Java / Spring / Code implementieren, um dies zu tun, nicht direkt über eine SQL-Abfrage. Jede Idee, wie dies mit dem folgenden Code zu tun ist: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) und ich habe dies über eine Datenbankabfrage gelöst:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza

11

Ich denke, ein Spaltenwert in einer Fremdschlüsseltabelle sollte mit dem Spaltenwert der Primärschlüsseltabelle übereinstimmen. Wenn wir versuchen, eine Fremdschlüsseleinschränkung zwischen zwei Tabellen zu erstellen, bei der sich der Wert in einer Spalte (der der Fremdschlüssel sein wird) vom Spaltenwert der Primärschlüsseltabelle unterscheidet, wird die Nachricht ausgegeben.

Es wird daher immer empfohlen, nur die Werte in die Spalte Fremdschlüssel einzufügen, die in der Spalte Primärschlüsseltabelle vorhanden sind.

Zum Beispiel. Wenn die Primärtabellenspalte die Werte 1, 2, 3 hat und in der Fremdschlüsselspalte die eingefügten Werte unterschiedlich sind, wird die Abfrage nicht ausgeführt, da erwartet wird, dass die Werte zwischen 1 und 3 liegen.


11

Führen Sie die folgenden Schritte aus, bevor Sie der Tabelle einen Fremdschlüssel hinzufügen

  1. Stellen Sie sicher, dass die Tabelle leer sein muss oder dass die Spaltendaten übereinstimmen sollten.
  2. Stellen Sie sicher, dass es nicht null ist.
  3. Wenn die Tabelle enthält, gehen Sie nicht zum Entwerfen und Ändern, sondern manuell.

    Tabelle ändern Tabelle 1 Verweise auf Fremdschlüssel (Spaltenname) hinzufügen Tabelle 2 (Spaltenname)

    alter table Tabelle 1 alter column Spaltenname Attribut nicht null


10

Bereinigen Sie Ihre Daten aus Ihren Tabellen und stellen Sie dann eine Beziehung zwischen ihnen her.


Danke, max. Es hat bei mir funktioniert, wenn sie Daten haben, auch wenn die Beziehungen perfekt sind. Der Befehl Update-Database funktioniert nicht.
Robert Jebakumar2

Es ist nicht erforderlich, Daten zu entfernen, solange sie gemäß dem erstellten Fremdschlüssel gültig sind.
Jumxozizi

7

Probieren Sie DELETEdie aktuellen Daten aus tblDomare.PersNR. Weil die Werte in tblDomare.PersNRmit keinem der Werte in übereinstimmten tblBana.BanNR.


@agenc habe ich deine Frage beantwortet?
Denker Bell

3

Ich hatte auch diesen Fehler, als Smutje erneut darauf hinwies, dass Sie keinen Wert in der Fremdschlüsselspalte Ihrer Basis-Fremdschlüsseltabelle haben, der nicht in Ihrer Referenztabelle enthalten ist, dh (jeden Wert in Ihrer Basis-Fremdschlüsseltabelle (Wert einer Spalte) Fremdschlüssel) muss sich auch in Ihrer Referenztabellenspalte befinden) Es ist gut, zuerst Ihre Basis-Fremdschlüsseltabelle zu leeren und dann Fremdschlüssel zu setzen


2

Die Daten, die Sie in eine Tabelle (tbldomare) eingegeben haben, stimmen nicht mit den Daten überein, die Sie der Primärschlüsseltabelle zugewiesen haben. schreibe zwischen tbldomare und füge dieses Wort hinzu (mit nocheck) und führe dann deinen Code aus.

Sie haben beispielsweise eine Tabelle mit diesen Daten eingegeben

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

und Sie haben eine foreign keyTabelle zugewiesen , die nur akzeptiert werden soll 1,2,3.

Sie haben zwei Lösungen. Eine besteht darin, die Daten zu löschen, die Sie in eine Tabelle eingegeben haben, und dann den Code auszuführen. ein anderes ist, dieses Wort zu schreiben (mit nocheck), es zwischen deinen Tabellennamen zu setzen und so hinzuzufügen

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

2

Dies passiert mir, da ich beim Entwerfen meiner Datenbank bemerke, dass ich meinen Startwert in meiner Haupttabelle ändere. Jetzt hat die relationale Tabelle keinen Fremdschlüssel in der Haupttabelle.

Also muss ich beide Tabellen abschneiden, und es funktioniert jetzt!


2

Sie sollten sehen, ob Ihre Tabellen Daten in den Zeilen enthalten. Wenn „ja“ , dann sollten Sie die Tabelle (n) gestutzt oder sonst können Sie ihnen die gleiche Anzahl von Daten zu haben , machen tblDomare.PersNRzu tblBana.BanNRund umgekehrt.


2

Smutje hat recht und Chad HedgeCock bot ein großartiges Beispiel für Laien. Ich möchte auf dem Beispiel von Chad aufbauen, indem ich eine Möglichkeit anbiete, diese Datensätze zu finden / löschen. Wir werden den Kunden als Elternteil und die Bestellung als Kind verwenden. CustomerId ist das allgemeine Feld.

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

Wenn Sie diesen Thread lesen ... erhalten Sie Ergebnisse. Dies sind verwaiste Kinder. Wählen Sie * aus Order Child left join Customer Parent auf Child.CustomerId = Parent.CustomerId, wobei Parent.CustomerId null ist. Beachten Sie die Zeilenanzahl unten rechts.

Überprüfen Sie, mit wem Sie diese Zeilen löschen möchten!

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

Führen Sie das erste Bit aus. Überprüfen Sie die Zeilenanzahl = was Sie erwartet haben

den Tran begehen

commit tran 

Achtung. Jemandes schlampige Programmierung hat Sie in dieses Chaos gebracht. Stellen Sie sicher, dass Sie das Warum verstehen, bevor Sie die Waisenkinder löschen. Vielleicht muss der Elternteil wiederhergestellt werden.


Danke für die Antwort. Ich spiele mit der Stackoverflow-Datenbank (eigentlich Gamedev) und habe zwei NULL-Werte gefunden, als ich JOIN Badges with Users verlassen habe. Kein Wunder, dass die Einschränkungen nicht funktionierten ...
Nicholas Humphrey

1

In meinem Szenario mit EF habe ich beim Versuch, diesen neuen Fremdschlüssel für vorhandene Daten zu erstellen, fälschlicherweise versucht, die Daten nach dem Erstellen des Fremdschlüssels zu füllen (Verknüpfungen herzustellen).

Das Update besteht darin, Ihre Daten vor dem Erstellen des Fremdschlüssels zu füllen, da alle überprüft werden, um festzustellen, ob die Links tatsächlich gültig sind. Es könnte also unmöglich funktionieren, wenn Sie es noch nicht ausgefüllt haben.


1

Ich habe ein Problem in meinem Projekt.

Geben Sie hier die Bildbeschreibung ein

In der untergeordneten Tabelle gibt es keine Datensatz-ID gleich 1 und 11

Magier

Ich habe die Tabelle DEAL_ITEM_THIRD_PARTY_PO eingefügt, deren ID 1 und 11 entspricht, dann kann ich FK erstellen


0

Bitte löschen Sie zuerst Daten aus dieser Tabelle und führen Sie dann die Migration erneut aus. Sie werden Erfolg haben


0

Wenn Sie in Tabelle B einen Fremdschlüssel definieren, der auf den Primärschlüssel von Tabelle A verweist, bedeutet dies, dass sich ein Wert in B in A befinden muss, um inkonsistente Änderungen an den Tabellen zu vermeiden.

In Ihrem Beispiel enthalten Ihre Tabellen:

tblDomare mit PRIMARY KEY (PersNR):

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

tblBana:

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

Diese Aussage:

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

sagt, dass jede Zeile tblDomaremit dem Schlüssel PersNReine Entsprechung in der Tabelle tblBanaauf dem Schlüssel haben muss BanNR. Ihr Fehler liegt darin, dass Sie Zeilen tblDomareohne Entsprechung eingefügt haben tblBana.

2 Lösungen zur Behebung Ihres Problems: - Fügen Sie entweder Zeilen tblBanamit BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines intblDomare that have no correspondance intblBana` hinzu (aber Ihre Tabelle wäre leer).

Allgemeiner Hinweis : Sie sollten die Fremdschlüsseleinschränkung haben, bevor Sie die Tabellen füllen. Fremdschlüssel sollen verhindern, dass der Benutzer der Tabelle die Tabellen mit Inkonsistenzen füllt.


-3

und nur zu Ihrer Information, falls Sie alle Ihre Datenreferenzprüfungen durchführen und keine fehlerhaften Daten finden ... anscheinend ist es nicht möglich, eine Fremdschlüsseleinschränkung zwischen zwei Tabellen und Feldern zu erstellen, wobei diese Felder der Primärschlüssel in beiden Tabellen sind! Frag mich nicht, woher ich das weiß.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.