Bir alt satır eklenemiyor veya güncellenemiyor: yabancı anahtar kısıtlaması başarısız


174

tablo 1

+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| UserID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| Password | varchar(20) | NO   |     |         |                |
| Username | varchar(25) | NO   |     |         |                |
| Email    | varchar(60) | NO   |     |         |                |
+----------+-------------+------+-----+---------+----------------+

Tablo 2

+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| UserID           | int(11)      | NO   | MUL |         |                |
| PostID           | int(11)      | NO   | PRI | NULL    | auto_increment |
| Title            | varchar(50)  | NO   |     |         |                |
| Summary          | varchar(500) | NO   |     |         |                |
+------------------+--------------+------+-----+---------+----------------+

Hata:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: 
Cannot add or update a child row: a foreign key constraint fails 
(`myapp/table2`, CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`UserID`) 
REFERENCES `table1` (`UserID`)) 

Neyi yanlış yaptım? Http://www.w3schools.com/Sql/sql_foreignkey.asp adresini okudum ve neyin yanlış olduğunu göremiyorum.


4
Hatayı tetikleyen sorguyu gönderebilir misiniz?
Nemli

38
Özetle, içinde table2.UserIDolmayan bir değer eklemeye / güncellemeye çalışıyorsunuz table1.UserID.
Joe Stefanelli

Neden olduğundan emin değilim, ancak veritabanımı bir Windows ortamından Linux'a taşıdıktan sonra, bir ilişkiyi silmem ve yeniden oluşturmam gerekiyordu (o zaman sorunu fark ettim). Değer vardı, ancak ilişkiyi kaldırmak ve yeniden eklemek sorunu düzeltti. Bunu yaparken çok dikkatli olmanız gerekebilir.
johnsnails

Yanıtlar:


235

Bu hatayı, table2o UserIDanda depolanan değerlere göre alan için geçerli bir değeri olmayan bir satır eklemeye / güncellemeye çalıştığınız için alıyorsunuz table1. Daha fazla kod gönderirseniz, belirli bir nedeni teşhis etmenize yardımcı olabilirim.


PreparedStatement st = connection.prepareStatement ("table2'ye ekle (UserID, PostID, Title, Özet)" + "değerler (UserID,?,?,?)");
Tom

15
downvote'un ne için olduğundan emin değilim; cevabım tamamen geçerli ve doğru.
Brian Driscoll

Hmm ... Hazırladığınız ifadede adlandırılmış parametreleri adlandırılmamış parametrelerle karıştırmak kesinlikle iyi bir fikir değil. execute deyiminde belirtilen UserID için uygun değerle "değerler (?,?,?,?)" olmalıdır.
Brian Driscoll

Bu yüzden table1 kullanıcı kimliği almak için başka bir SQL deyimi yapmak gerekir?
Tom

5
Büyük olasılıkla 0, bu durumda Null ile değiştirin
Jeffrey Nicholson Carré

123

Bu , içinde olmayan table2bir UserIDdeğere eklemeye çalıştığınız anlamına gelir table1.


104

Basit bir hack, masada herhangi bir işlem yapmadan önce yabancı anahtar kontrollerini devre dışı bırakmak olabilir. Sadece sorgula

SET FOREIGN_KEY_CHECKS=0

Bu, diğer tablolarla yabancı anahtar eşleşmesini devre dışı bırakır. Tablo ile işiniz bittiğinde tekrar etkinleştirin

SET FOREIGN_KEY_CHECKS=1

Bu benim için çok işe yarıyor.


Bunu nasıl kullanırım?
Pune'dan Sachin,

2
@SachinfromPune sadece SET FOREIGN_KEY_CHECKS = 0 ekleyin; mysql dosyasının başlangıcında ve SET FOREIGN_KEY_CHECKS = 1; mysql dosyasının sonunda, verileri yeniden
içe aktar

1
Bu sorunlu değil mi? Referans bütünlüğünü kaybedersiniz, değil mi?
roadrunner66

Referans bütünlüğü, doğru dizin girişlerinin varlığıyla desteklenir. Anahtarlarınızı ve dizinlerinizi doğru girdiğiniz sürece, toplu giriş sırasında tuş kontrolünü devre dışı bırakabilmeniz gerekir.
Vernon Keenan

46

Başka bir garip durum keşfettim: Yanlışlıkla bir InnoDB tablosundan bir MyISAM tablosuna yabancı bir anahtar oluşturursanız, veriler başka şekilde geçerli olsa bile MySQL bu hatayı ekleme sırasında atar.

Bkz. Http://nick.zoic.org/art/mysql-foreign-key-error/


1
Evet, aynı problemim var. İki tablo InnoDB olmalıdır!
emeraldhieu

2
Aynı sorunu yaşadım, bahşiş için teşekkürler. Tabloların MyISAM'den InnoDB'ye nasıl dönüştürüleceğine dair MySQL belgelerine bir link dev.mysql.com/doc/refman/5.7/en/… TLDR: ALTER TABLE table_name ENGINE = InnoDB;
Guilherme Vaz

Gerçekten de, veritabanımdaki durum buydu. MyISAM motorunu InnoDB olarak değiştirmeye karar verdim. Son olarak, istediğim gibi veritabanı ile çalışabilirim.
Mike

17

Bu hatayı alıyorsunuz çünkü üzerinde olmayan bazı int değerleri table2.UserIDvar table1.UserID(Sanırım table2.UserIDbu yabancı anahtarı yaratmadan önce değeri manuel olarak ayarladınız).
Bu sahne için bir örnek: table1.UserID1,2,3 table2.UserIDdeğerlerini alın ve 4 değerlerini alın (manuel olarak ekleyin). Yabancı bir anahtar yaparken Yani, onlar bulamıyor UserID = 4gelen table1ve hata ocurse edecektir.
Bu hatayı düzeltmek için, sadece kaldırmak UserID = 4gelen table2veya her ikisi boşaltmak ve sonra yabancı anahtar oluşturabilir ve.
İyi şanslar!


11

Anlamak biraz zaman aldı. Basitçe söylemek gerekirse, diğer tabloya başvuran tablo zaten veri içeriyor ve değerlerinden biri veya daha fazlası üst tabloda mevcut değil.

Örneğin, Table2 aşağıdaki verilere sahiptir:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

Tablo 1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com

Table2 ALTER için deneyin ve bir yabancı anahtar ekleyin, o zaman User1 = 5 Table1 içinde yok çünkü sorgu başarısız olur.


10

Tablo 2'de yabancı anahtarı oluşturmadan önce tablo 1'e bir satır eklediyseniz, yabancı anahtar kısıtlama hatası alırsınız, çünkü otomatik artış değeri tablo 2'de tablo 1 ve 1'de 2'dir. Bunu çözmek için tablo 1'i kısaltın ve otomatik artış değerini 1 olarak ayarlayın. Sonra tablo 2'yi ekleyebilirsiniz.


10

MyISAM yabancı anahtar ve işlem desteklenmediği için veritabanı motorunu InnoDB olarak ayarladığınızdan emin olun


2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra

7

Sadece küçük bir düzeltme: JoinColumn 'u Table1 ve' UserID 'alanı' inserttable = false 've' nullable = true 'Tablo2'de olun.

Table1 Entity'de:

@OneToMany(targetEntity=Table2.class, cascade = CascadeType.ALL)
@JoinColumn(name = "UserID", referencedColumnName = "UserID", nullable = true)
private List<Table2> table2List;

Table2 Entity'de:

@Column(insertable = false, nullable = true)
private int UserID;

Bu cevap sorunumu tamamen çözdü, bunu paylaştığın için çok teşekkür ederim. Benim için anahtar, alt nesne (tablo) foraeing anahtarı olarak kullanıyorum dosyaya @Column (insertable = false, nullable = true) ekliyordu.
Israelm

6

Aynı sorunu yaşadım, çözüm kolay.

Üst tabloda olmayan bir alt tabloya kimlik eklemeye çalışıyorsunuz .

InnoDB, bazen değer eklemeden auto_increment sütununu bazen artıran bir hataya sahip olduğundan, örneğin, INSERT ... ON DUPLICATE KEY


ciddi anlamda? mevcut olmayan bir kimlik referansı eklemeyin ... sadece kontrol edin
Blaztix

5

Benzer bir sorunum vardı. İçeriği olan bir tabloya yabancı anahtar uygulamaya çalışıyorsunuz ve sütun null alınamıyor. İki seçeneğiniz var.

  1. Yabancı anahtar kısıtlamaları uygulamak istediğiniz sütunu boş bırakılabilir yapın. Bu şekilde, bazı alanların boşaltılabileceğini bilerek yabancı anahtar geçerli olacaktır. ( Ben de bunu yaptım. )
  2. Yabancı anahtar kısıtlaması uygulamak istediğiniz sütunu oluşturun, yabancı anahtarı sütuna eklemek için bir sorgu yazın ve ardından yabancı anahtar kısıtlamalarını uygulayın. ( Bunu denemedim ama işe yaramalı )

4

Yabancı anahtara eklediğiniz değerin üst tabloda bulunduğundan emin olun. Bu bana yardımcı oldu. Örneğin , user_id = 2içine bir eklerseniz table.2, ancak a table.1yoksa user_id = 2, kısıtlama bir hata atar. Benimki 1452 numaralı hata koduydu. Umarım bu aynı problemi olan herkese yardımcı olur!


3

Aynı sorunu yaşadım ve bunun nedeni, yabancı anahtar eklemeden önce ilk tabloda bir satır olmasıydı.


1

Ben de aynı sorunla karşı karşıya ve sorun benim ana tablo girişleri değeri yabancı anahtar tablo değeri ile eşleşmiyordu. Lütfen tüm satırları temizledikten sonra deneyin ..


Kısıtlama, Tablo2'de başvurulan kullanıcıların Tablo1'de zaten tanımlanmış olmasını gerektirir.
sorak

1

Başkaları tarafından sağlanan çözümler işe yaramazsa. Sonra üst ve alt tabloların veritabanı motorları kontrol etmelisiniz. Benim durumumda, üst tabloların motoru "MyISAM" olarak ayarlanmış, InnoDB olarak değiştirerek sabit.

Umarım bu benim gibi sıkışmış olanlara yardımcı olur.


1

Veritabanındaki bir kaskadına ondelete alanı koymamalısınız.

Bu yüzden onDelete alanını RESTRICT olarak ayarlayın

İyi şanslar ♥


0

Yine bu hatayı veren garip bir dava daha. Yabancı anahtarlarımı id birincil anahtarına yanlışlıkla göndermiştim. Bunun nedeni yanlış değiştirme tablosu komutlarıdır. BİLGİ_SCHEMA tablosunu sorgulayarak bunu öğrendim (Bu stackoverflow yanıtına bakın)

Tablo o kadar karışıktı ki, herhangi bir ALTER TABLE komutu ile düzeltilemedi . Sonunda masayı düşürdüm ve yeniden inşa ettim. Bu bütünlükten kurtuldu Hata.


0

userIDSütunu eklediğinizde, oluşturulduğu belirli bir tablo için varsayılan bir değere sahip olacak bir veri vardır, 0ancak sütunuNOT NULL


0

Ayrıca şu hatayı aldım: "Bir alt satır eklenemiyor veya güncellenemiyor: yabancı anahtar kısıtlaması başarısız". Üst tabloya yeni bir satır eklerken hatayla karşılaştım

Sorun, yabancı anahtar kısıtlamasının alt tablo yerine üst tabloda tanımlanmış olmasıydı.


0

Tablolar arasında mysql dizini veya ilişki kullanıyorsanız, önce sütunları silin (örneğin: city_id) ve aynı ada sahip yeni sütunlar oluşturun (örneğin: city_id) Sonra tekrar deneyin ...


0

Tablonun içerdiği mevcut veriler var mı? Öyleyse, yabancı anahtar eklemek istediğiniz tablodaki tüm verileri temizlemeyi deneyin. Ardından kodu tekrar çalıştırın (yabancı anahtar ekleyin).

Bu sorunla pek çok kez karşılaştım. Bu, tablodaki tüm verilerin silinmesi, varolan bir tabloya yabancı anahtar eklemek istediğinizde işe yarar.

Umarım bu işe yarar :)


0

Tablo2'deki UserID alanının dizinlerini silin. Benim için uygun


0

Bu hata, üst tablonun birincil anahtarında bulunmayan değerlere sahip bir yabancı anahtar eklemek istediğinizde oluşur. Table2 içindeki yeni yabancı anahtar UserID'nin table1 birincil anahtarında var olan değerlere sahip olduğundan emin olmalısınız, bazen varsayılan olarak null veya 0'a eşittir.

Önce table2 içindeki yabancı anahtarın tüm alanlarını table1'in birincil anahtarında bulunan bir değerle güncelleyebilirsiniz.

update table2 set UserID = 1 where UserID is null

Farklı UserID'ler eklemek istiyorsanız, her satırı istediğiniz değerlerle değiştirmeniz gerekir.


-1

alt tablo yabancı anahtar kısıtlaması başarısız oluyor

Bu sorun aşağıdaki nedenlerden dolayı ortaya çıkabilir:

Spring mvc içinde yapıyorsanız, bazen mysql id türünü tanıyamaz çünkü id türünü açıkça tanımlamanız gerekir. böylece varlık sınıfınızdaki her iki tabloda da açıkça ayarladınız@GeneratedValue (strategy = GenerationType.IDENTITY)

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.