ALTER TABLE ifadesi, FOREIGN KEY kısıtlamasıyla çakıştı


184

Masama yabancı anahtar eklemeye çalışırken bir sorunum var tblDomare; burada neyi yanlış yapıyorum?

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

Hata mesajı:

ALTER TABLE deyimi, "FK_ tblDomare _PersN__5F7E2DAC" FOREIGN KEY kısıtlamasıyla çakıştı. Çakışma "almu0004" veritabanında, "dbo.tblBana" tablosunda, "BanNR" sütununda oluştu.

Yanıtlar:


333

Eğer bir yabancı anahtarı oluşturmak için çalıştık, çünkü oluştu tblDomare.PersNRiçin tblBana.BanNRama / ve değerleri tblDomare.PersNRiçinde değerlerden herhangi biriyle eşleşmedi tblBana.BanNR. Referans bütünlüğünü ihlal eden bir ilişki oluşturamazsınız.


87
Bu benim için bir cevaptı, ama yine de sorunun nerede olduğunu fark etmekte zorlandım, bu yüzden bir layman örneği vereceğim. 'Siparişler' adlı bir tablonuz ve 'Müşteriler' adlı bir tablonuz varsa ve bazı eski müşterileri sildiyseniz, ancak siparişlerini silmediyseniz, Siparişler'den yabancı anahtar yapmaya karar verirseniz bu hatayı alırsınız. .İD. Bazı siparişler artık karşılık gelen bir müşteriye sahip değil, bu nedenle yabancı anahtar eklemek imkansız.
Chad Hedgcock

10
İşte yanlış değerleri kontrol etmek için bir sorgu: referRable.referenceColumn = referrerTable.referenceColumn null;
jumxozizi

6
Bir tutamda, FK eklemek için "NOCHECK İLE ALTER TABLE tablename ..." seçeneğini de kullanabilirsiniz. Bu, mevcut veriler kısıtlamayı kırsa bile ilişkiyi eklemenize olanak tanır. Öncelikle verilerinizi temizlemek daha iyidir, ancak bu en azından size başka bir seçenek sunar.
DaveInMaine

2
@DaveInMaine Biri "istendiğinde" veritabanı kısıtlamalarını devre dışı bırakırsa, neden kendileri ile başa bela başa çıkmak için sormak ve veritabanı bütünlüğü ile ilgilenmiyorsa sadece atlamak değil.
Smutje

1
ne berbat bir hata mesajı. daha önce gördüm ama şimdi bir şey bozuk olduğunu düşünerek beni tamamen nöbetçi yakaladı
Simon_Weaver

43

Bu sorgu benim için çok faydalı oldu. Eşleşmesi olmayan tüm değerleri gösterir

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

37

Bu çözümü deneyin:

Tablonuzda, ilişkilendirilmiş değeri birincil anahtar tablosu olarak kullanmak istediğiniz tabloda bulunmayan bir veri öğesi var. Tablonuzu boş bırakın veya ilişkili değeri ikinci tabloya ekleyin.


29

Yabancı anahtarı, yabancı anahtarı ihlal eden verilere izin veren ALTER TABLE tablename WITH NOCHECK ... kullanarak oluşturmak mümkündür.

FK eklemek için "ALTER TABLE tablename NOCHECK ..." seçeneği - Bu çözüm benim için çalıştı.


17
Bu tür ihlallere izin vermenin yabancı anahtar kısıtlamasının amacını bozduğunu unutmayın.
yeniden düzenlendi

Tehlikeli...!!! Yalnızca şu anda tablodaki verileri kaybetmek istemiyorsanız kullanılmalıdır. Ama o zaman bile, neden bir yedekleme yapmıyor ve daha sonra geçersiz ID'leri kaldırmıyorsunuz.
Andrei Bazanov

Ben doğrudan SQL sorgusu, herhangi bir ideia nasıl aşağıdaki kod ile bunu yapmak için java / bahar / kod yoluyla uygulamak gerekir: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) ve ben bu veritabanı sorgusu ile çözmek yaptım:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza

11

Yabancı anahtar tablosundaki bir sütun değeri, birincil anahtar tablosunun sütun değeriyle eşleşmelidir. Bir sütunun içindeki değerin (yabancı anahtar olacak) birincil anahtar tablosunun sütun değerinden farklı olduğu iki tablo arasında bir yabancı anahtar kısıtlaması oluşturmaya çalışıyorsak, mesajı atar.

Bu nedenle, her zaman yalnızca Birincil anahtar tablosu sütununda bulunan Yabancı anahtar sütununa bu değerlerin girilmesi önerilir.

Örn. Birincil tablo sütunu 1, 2, 3 değerlerine sahipse ve Yabancı anahtar sütununda eklenen değerler farklıysa, değerler 1 ve 3 arasında olmasını beklediğinden sorgu yürütülmez.


11

Tabloya Yabancı anahtar eklemeden önce aşağıdakileri yapın

  1. Tablonun boş olduğundan veya Sütun verilerinin eşleştiğinden emin olun.
  2. Boş olmadığından emin olun.
  3. Tablo içeriyorsa tasarım ve değişikliğe gitmeyin, elle yapın.

    tablo değiştirme Tablo 1 yabancı anahtar ekleme (Sütun Adı) başvuruları Tablo 2 (Sütun Adı)

    tablo değiştirme Tablo 1 sütun değiştirme sütun Adı özniteliği boş değil


10

Tablolarınızdan verilerinizi temizleyin ve aralarında ilişki kurun.


Teşekkürler, maks. İlişkileri mükemmel olsa bile verileri varsa benim için çalıştı Güncelleme-Veritabanı komutu çalışmaz.
Robert Jebakumar2

Oluşturulan yabancı anahtara göre geçerli olduğu sürece hiçbir veri kaldırılmasına gerek yoktur.
jumxozizi

7

DELETEAdresinden geçerli verileri deneyin tblDomare.PersNR. Çünkü içindeki değerler, içindeki tblDomare.PersNRherhangi bir değerle eşleşmedi tblBana.BanNR.


@agenc sorunuzu cevapladım mı?
Thinker Bell

3

Smutje reffered gibi bu hatayı vardı referans tablonuzda olmayan temel yabancı anahtar tablonuzun yabancı anahtar sütununda bir değer olmadığından emin olun (temel yabancı anahtar tablonuzdaki her değer (bir sütun değeri) yabancı anahtar) da referans tablo sütununda olmalıdır) temel yabancı anahtar tablonuzu boşaltmak için önce iyi sonra yabancı anahtarları ayarlamak


2

tabloya (tbldomare) girdiğiniz veriler, birincil anahtar tablosu atadığınız verilerle eşleşmiyor. tbldomare arasına yazın ve bu kelimeyi (nocheck ile) ekleyin ve kodunuzu yürütün.

örneğin bu tabloya bir tablo girdiniz

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

ve foreign keysadece kabul etmek için bir masa atadınız 1,2,3.

iki çözümünüz var, bir tabloya girdiğiniz verileri silip kodu yürütün. bir diğeri ise bu kelimeyi (nocheck ile) tablo adınızın arasına koyun ve şöyle ekleyin

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

2

Bu benim başıma geliyor, çünkü veritabanımı tasarladığım için, tohumumu ana masamda değiştirdiğimi fark ettim, şimdi ilişkisel tablonun ana masada yabancı bir anahtarı yok.

Bu yüzden her iki tabloyu da kesmem gerekiyor ve şimdi çalışıyor!


2

Tablolarınızda satırlarda veri olup olmadığını görmelisiniz. Eğer "evet" o zaman tablo (s) kesmek gerekir yoksa bunları verilerde aynı sayıda yapabilirsiniz tblDomare.PersNRetmek tblBana.BanNRve mengene-ayet.


2

Smutje doğrudur ve Chad HedgeCock harika bir layman örneği sundu. Bu kayıtları bulmanın / silmenin bir yolunu sunarak Çad'ın örneğini geliştirmek istiyorum. Müşteri'yi Ebeveyn ve Sipariş'i çocuk olarak kullanacağız. CustomerId ortak alandır.

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

Eğer bu konuyu okuyorsanız ... sonuçlar elde edersiniz. Bunlar yetim çocuklar. Sipariş * öğesinden * öğesini seçin Soldan Child.CustomerId = Parent.CustomerId Burada Parent.CustomerId öğesinin boş olduğu Customer Parent'a katılın.

Git ve bu satırları sileceğin kişiyi doğrula!

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

İlk biti çalıştırın. Bu satır sayısını kontrol edin = beklediğiniz değer

tran yap

commit tran 

Dikkatli ol. Birisi özensiz programlama sizi bu karmaşaya soktu. Yetimleri silmeden önce nedenini anladığınızdan emin olun. Belki de ebeveynin geri yüklenmesi gerekir.


Cevap için teşekkürler. Stackoverflow veritabanı (aslında gamedev) ile oynuyorum ve ben kullanıcılarla rozetleri sol zaman iki NULL bulundu. Kısıtlamaların işe yaramadığına şaşmamalı ...
Nicholas Humphrey

1

Benim senaryomda, EF kullanarak, mevcut veriler üzerinde bu yeni Yabancı Anahtar oluşturmaya çalıştıktan sonra, yanlış yabancı anahtar oluşturduktan sonra verileri doldurmak (bağlantıları yapmak) çalışıyordum.

Çözüm, yabancı anahtar oluşturmadan önce verilerinizi doldurmaktır, çünkü bağlantıların gerçekten geçerli olup olmadığını görmek için hepsini kontrol eder. Henüz doldurmadığınız takdirde işe yaramayabilir.


1

Projemde bir sorunla karşılaşıyorum.

resim açıklamasını buraya girin

Alt tabloda, 1 ve 11'e eşit kayıt kimliği yok

sihirbaz

Kimlik 1 ve 11'e eşit olan DEAL_ITEM_THIRD_PARTY_PO tablosu ekledim ve sonra FK oluşturabilirim


0

Lütfen önce bu tablodaki verileri silin ve ardından taşımayı tekrar çalıştırın. Başarı elde edeceksiniz


0

Tablo B'de Tablo A'nın Birincil Anahtarını referans alan bir Yabancı Anahtar tanımladığınızda, değer B'de olduğunda A'da olması gerektiği anlamına gelir. Bu, tablolarda tutarsız değişiklikler yapılmasını önlemek içindir.

Örneğinizde, tablolarınız şunları içerir:

karşılaştırma tblDomare şununla PRIMARY KEY (PersNR):

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

tblBana:

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

Bu açıklama:

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

herhangi bir satır söylüyor tblDomareanahtarla PersNRtablodaki bir yazışmalar olmalıdır tblBanatuş üzerinde BanNR. Hatanızda, tblDomarekarşılık gelmeyen satırlar var tblBana.

Sorununuzu çözmek için 2 çözüm : - tblDomare tblBana` tblBanaile BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines insatır that have no correspondance inekleyin (ancak tablonuz boş olacaktır)

Genel öneri : tabloları doldurmadan önce Yabancı Anahtar kısıtlamanız olmalıdır. Yabancı anahtarlar, tablonun kullanıcısının tabloları tutarsızlıkla doldurmasını önlemek için buradadır.


-3

ve sadece FYI, tüm veri referans kontrollerinizi yapmanız ve hiçbir kötü veri bulmamanız durumunda ... görünüşe göre, iki tablo ve bu alanların her iki tabloda birincil anahtar olduğu alanlar arasında bir yabancı anahtar kısıtlaması oluşturmak mümkün değildir! Bana bunu nasıl bildiğimi sorma.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.