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

toから外部キーを作成しようとしたために発生しtblDomare.PersNRましたtblBana.BanNRが、/の値がtblDomare.PersNRのどの値とも一致しませんでしたtblBana.BanNR。参照整合性に違反する関係を作成することはできません。


87
これが私の答えでしたが、問題がどこにあるのかを理解するのにまだ苦労していたので、素人の例を挙げましょう。「Orders」という名前のテーブルと「Customers」という名前のテーブルがあり、古い顧客をいくつか削除したが、その注文は削除していない場合、Orders.CustomerIdからCustomersへの外部キーを作成すると、このエラーが発生します。 .Id。一部の注文には対応する顧客がいないため、外部キーを追加できません。
チャドヘッジコック2014年

10
不正な値をチェックするクエリは次のとおりです。referrerTableから個別のreferrerTable.referenceColumnを選択してください
jumxozizi

6
ピンチでは、「ALTER TABLE tablename WITH NOCHECK ...」オプションを使用してFKを追加することもできます。これにより、既存のデータが制約に違反しても、関係を追加できます。最初にデータをクリーンアップする方が明らかに優れていますが、これにより少なくとも別のオプションが提供されます。
DaveInMaine

2
@DaveInMaineデータベースの制約を「必要なときに」非アクティブ化する場合、そもそもなぜデータベースの整合性に関心がないのであれば、なぜそれをスキップするのではなく、なぜそれらをトラブルシューティングするのかを尋ねます。
Smutje

1
なんとお粗末なエラーメッセージ。以前にそれを見たが、何かが破損していると今考えているだけで私を完全に
油断

43

このクエリは私にとって非常に役に立ちました。一致しないすべての値が表示されます

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

37

この解決策を試してください:

主キーテーブルとして使用するテーブルに、関連付けられた値が存在しないデータアイテムがテーブルにあります。テーブルを空にするか、関連する値を2番目のテーブルに追加します。


29

ALTER TABLE tablename WITH NOCHECK ...を使用して外部キーを作成できます。これにより、外部キーに違反するデータが許可されます。

FKを追加するための「ALTER TABLE tablename WITH NOCHECK ...」オプション-この解決策は私にとってうまくいきました。


17
このような違反を許可すると、外部キー制約の目的が無効になることに注意してください。
改訂

危険な...!!!現在テーブルにあるデータを失いたくない場合にのみ使用してください。しかし、それでも、バックアップを実行してから、無効なIDを削除してみませんか。
Andrei Bazanov

これを行うには、java / spring / codeを介して実装する必要があります。SQLクエリを介して直接行うのではなく、次のコードでこれを行う方法を考えます。これ@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

おそらく、外部キーテーブルの列の値は、主キーテーブルの列の値と一致しているはずです。1つの列内の値(外部キーになる)が主キーテーブルの列値と異なる2つのテーブル間に外部キー制約を作成しようとすると、メッセージがスローされます。

そのため、主キーテーブルの列にある値のみを外部キー列に挿入することを常にお勧めします。

例のために。プライマリテーブルの列の値が1、2、3で、外部キーの列に挿入された値が異なる場合、値が1と3の間であることを想定しているため、クエリは実行されません。


11

テーブルに外部キーを追加する前に、次の操作を行います

  1. テーブルが空であるか、列データが一致していることを確認してください。
  2. nullでないことを確認してください。
  3. テーブルが含まれている場合は、設計および変更を行わない場合は、手動で行ってください。

    表1の変更外部キー(列名)参照の追加表2(列名)

    表の変更表1列の変更列名属性がNULLではありません


10

テーブルからデータを削除し、テーブル間の関係を作成します。


ありがとう、マックス。関係が完全であってもデータがある場合は、Update-Databaseコマンドが機能せず、うまくいきました。
robert jebakumar2

作成される外部キーに従って有効である限り、データを削除する必要はありません。
jumxozizi 2017

7

DELETEからの現在のデータを試してくださいtblDomare.PersNR。の値がtblDomare.PersNRのどの値とも一致しなかったためtblBana.BanNRです。


@agencはあなたの質問に答えましたか?
思想家の鐘

3

私もこのエラーがありました。Smutjeが、参照テーブルにないベース外部キーテーブルの外部キー列に値がないことを確認したためです(つまり、ベース外部キーテーブルのすべての値(ある列の値外部キー)も参照テーブルの列にある必要があります)ベースの外部キーテーブルを最初に空にしてから外部キーを設定すると便利です


2

テーブル(tbldomare)に入力したデータは、主キーテーブルに割り当てたデータと一致しません。tbldomareの間に書き込み、この単語を(チェックなしで)追加して、コードを実行します。

たとえば、テーブルtbldomarこのデータを入力した

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

そして、あなたforeign keyだけを受け入れるようにテーブルを割り当てました1,2,3

2つの解決策があります。1つは、テーブルに入力したデータを削除してから、コードを実行することです。別の方法は、この単語を(チェックなしで)書いて、テーブル名の間に置き、次のように追加します

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

2

これは私に起こります。データベースを設計しているので、メインテーブルのシードを変更していることに気付きました。リレーショナルテーブルにはメインテーブルの外部キーがありません。

だから私は両方のテーブルを切り捨てる必要があり、それは今うまくいきます!


2

テーブルの行にデータがあるかどうかを確認する必要があります。「はい」の場合は、テーブルを切り捨てるか、またはtblDomare.PersNRto tblBana.BanNRとvise-verse で同じ数のデータを持つようにすることができます。


2

Smutjeは正解で、Chad HedgeCockは素人の素晴らしい例を提供しました。それらのレコードを検索/削除する方法を提供することにより、チャドの例に基づいて構築したいと思います。親を顧客、子を注文とします。CustomerIdは共通フィールドです。

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

このスレッドを読んでいる場合...結果が得られます。これらは孤立した子供です。注文*から子を左に選択して、Customer ParentをChild.CustomerId = Parent.CustomerIdに結合します。ここで、Parent.CustomerIdはnullです。右下の行数に注意してください。

これらの行を削除する必要があることを誰とでも確認してください!

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)で遊んでいて、ユーザーとのバッジの結合を残したときに2つのNULLを見つけました。拘束が機能しなかったのも不思議ではありません...
ニコラスハンフリー

1

私のシナリオでは、EFを使用して、既存のデータにこの新しい外部キーを作成しようとすると、外部キーの作成後に誤ってデータを入力(リンクを作成)しようとしました。

修正は、外部キーを作成する前にデータを入力することです。リンクが実際に有効かどうかを確認するために、それらすべてをチェックします。そのため、まだ入力していない場合は機能しない可能性があります。


1

プロジェクトで問題が発生しました。

ここに画像の説明を入力してください

子テーブルには、1と11に等しいレコードIDはありません

魔道士

IDが1および11であるDEAL_ITEM_THIRD_PARTY_POテーブルを挿入した後、FKを作成できます


0

最初にそのテーブルからデータを削除してから、もう一度移行を実行してください。あなたは成功するでしょう


0

テーブルAの主キーを参照するテーブルBで外部キーを定義する場合、値がBにある場合、値はAにある必要があります。これは、テーブルへの一貫性のない変更を防ぐためです。

あなたの例では、あなたのテーブルは以下を含みます:

tblDomare with PRIMARY KEY (PersNR)

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

tblBana:

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

この文:

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

tblDomarekey を含む行はすべて、keyのPersNRテーブルtblBanaに対応する必要があると述べていますBanNR。エラーは、にtblDomare対応しない行が挿入されているためですtblBana

2つのソリューションは、いずれかの行を追加します- :あなたの問題を解決するためtblBanaBanNR in (6811034679, 7606091347, 8508284163) - or remove all lines intblDomare that have no correspondance intblBana`(しかし、あなたのテーブルは空になります)

一般的なアドバイス:テーブルにデータを入力する前に、外部キー制約が必要です。外部キーは、テーブルのユーザーがテーブルに矛盾を埋めることを防ぐためにあります。


-3

参考までに、すべてのデータ参照チェックを行って不良データが見つからない場合...どうやら、2つのテーブルとフィールドの間に外部キー制約を作成することはできません。これらのフィールドは両方のテーブルの主キーです!どうやってこれを知っているのか尋ねないでください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.