SQL “Cannot add or update a child row” hatası, child tablodaki foreign key değerinin parent tabloda bulunmamasıyla oluşur. Önce parent kaydın varlığını, sonra INSERT veya UPDATE ile gönderdiğin foreign key değerini kontrol etmelisin.
Bu hata çoğunlukla sorgu sözdiziminden değil, iki tablo arasındaki ilişkinin geçersiz olmasından kaynaklanır. Çözümün mantığı basittir: Önce referans verilen kaydı doğrula, ardından child kaydı ekle veya güncelle.
SQL "Cannot add or update a child row" hatası ne anlama gelir?

Parent tablo, child tablonun bağlanacağı değerlerin bulunduğu tablodur. Child tablo ise bu değeri foreign key ile saklar. Örneğin users parent, orders child tabloysa orders.user_id alanı, her siparişin hangi kullanıcıya ait olduğunu users.id üzerinden belirtir. Referans bütünlüğü, child kaydın geçerli bir parent kayda işaret etmesini sağlar.
Bu nedenle orders.user_id alanına 42 gönderdiğinde, sistem ilgili foreign key denetimini yapıyorsa users içinde id = 42 kaydını arar. Kayıt yoksa yeni sipariş satırı eklenemez. Aynı mantık, mevcut bir siparişin user_id değerini geçersiz bir kullanıcı numarasıyla değiştirmeye çalıştığında da geçerlidir.
Başlıktaki İngilizce hata metni, MySQL hata referansında ER_NO_REFERENCED_ROW_2 ve 1452 ile ilişkilendirilir. Ancak hata kodu, ekranda görünen kısıt ayrıntıları ve denetimin ne zaman yapıldığı kullandığın veritabanı motoruna göre değişebilir. Örneğin MySQL belgeleri, InnoDB ile NDB için foreign key kontrollerinin zamanlamasında farklılıklar tanımlar. Bu nedenle kendi hata çıktındaki tablo ve kısıt adını ayrıca incelemelisin.
INSERT hatasını users ve orders örneğiyle çözme
Aşağıdaki örnekte users.id referans verilen parent alanı, orders.user_id ise bu alanı gösteren foreign key alanıdır. Örneğin, orders.user_id için FOREIGN KEY (user_id) REFERENCES users(id) tanımının etkin olduğunu varsayalım.
-- users tablosunda henüz id = 42 olan bir kayıt yok
INSERT INTO orders (id, user_id) VALUES (1001, 42);
-- Önce parent kayıt oluşturulur
INSERT INTO users (id) VALUES (42);
-- Ardından aynı sipariş yeniden eklenir
INSERT INTO orders (id, user_id) VALUES (1001, 42);
Beklenen sonuç: İlk INSERT, örnek şemada referans verilen users.id = 42 kaydı bulunmadığı için reddedilir. Parent kayıt eklendikten sonra ikinci INSERT, başka bir kısıt yoksa ilerler. Bu sonuç, orders.user_id üzerindeki foreign key denetiminin etkin olduğu varsayımına dayanır.
Benzer teknik hata mesajlarını sorgu, şema ve veri ilişkisi açısından okumayı öğrenmek için yazılım öğrenmeye yönelik blog içeriklerini inceleyebilirsin.
UPDATE ve şema kontrollerini neden ayrı yapmalısın?

UPDATE sırasında bu hatayı görüyorsan önce iki şeyi doğrula: orders.user_id alanına yazılacak değer nedir ve bu değer users tablosunda gerçekten var olan bir idye karşılık geliyor mu? Parent kayıt ile sorguya gönderilen değer aynı anda kontrol edilmeden sorunun veri mi yoksa şema mı olduğu netleşmez.
UPDATE orders
SET user_id = 999
WHERE id = 42;
Bu örnekte id = 42 olan siparişin bulunduğunu, fakat users tablosunda id = 999 kaydının olmadığını varsayalım. MySQL'de foreign key destekleyen depolama motorlarında, child satırda karşılığı olmayan bir foreign key değeri oluşturan UPDATE işlemi reddedilir. Beklenen sonuç, siparişin user_id = 999 ile ilişkilendirilmemesidir; hata metni MySQL'de başlıktaki biçimde görülebilir.
Önce veri sorununu ele
Önce güncellemede kullanacağın kesin değeri ara:
SELECT id
FROM users
WHERE id = 999;
Sorgu satır döndürmüyorsa sorun veridedir: 999 geçerli bir parent anahtar değildir. Satır dönüyorsa, uygulamanın gerçekten aynı değeri sorguya gönderdiğini kontrol et; ardından ilişkinin tanımını incele.
Şema kontrolü farklı bir soruyu yanıtlar
Parent kaydın bulunup bulunmadığı ve gönderilen değerin doğruluğu işlem anındaki veri kontrolüdür. orders.user_id ile users.id sütunlarının türleri ve ilişki tanımı ise şema kontrolüdür. Bu ayrım, eksik kaydı sütun tasarımıyla karıştırmanı önler.
SHOW CREATE TABLE users;
SHOW CREATE TABLE orders;
MySQL'de foreign key ile referans verilen sütunların benzer veri türlerine sahip olması gerekir; INTEGER veya DECIMAL gibi türlerde boyut ve işaret, karakter sütunlarında ise karakter kümesi ile sıralama kuralı önemlidir. Bunlar MySQL'e ait uyumluluk ölçütleridir; başka bir veritabanı motorunda kendi kurallarını ayrıca incelemelisin. SHOW CREATE TABLE çıktısında orders.user_id alanının gerçekten hangi tablo ve sütunu referans verdiğini de görürsün.
Dört adımda parent-child kontrol listesi
- Parent kayıt var mı?
SELECTsorgusunu,INSERTveyaUPDATEişleminde kullandığın kesin değerle çalıştır. Sonuç boşsa önce geçerli parent kaydı oluşturulmalı ya da doğru değer kullanılmalıdır. - Sorguya gönderilen foreign key değeri doğru mu? Parametre, değişken veya form verisi kullanıyorsan çalıştırılan değeri denetle. Test ettiğin
idile sorguya giden değer farklı olabilir. - Referans veren ve referans verilen sütunlar şema açısından uyumlu mu? Tablo tanımlarını karşılaştır; foreign key'nin hedeflediği sütunu, veri türü ayrıntılarını ve kullandığın motorun ilgili kurallarını kontrol et.
- Parent kayıt child işleminden önce mi oluşturuluyor? İşlem sırasını gözden geçir. Yeni bir
orderskaydı eklemeden veyauser_iddeğerini değiştirmeden önce ilgiliuserskaydının oluşturulduğundan emin ol.
Bu sırayı izlemek, hata mesajını deneme-yanılma yerine kısa bir teşhis akışına dönüştürür. Sen de programlama öğrenme hedeflerinde kişiye özel ilerlemek istiyorsan birebir özel ders programı sayfasındaki kapsamı inceleyebilirsin.
Sık Sorulan Sorular
Parent kayıt varken bu hata neden devam eder?
Önce kontrol ettiğin id ile UPDATE sorgusunun gerçekten yazdığı değerin aynı olduğundan emin ol. Değer aynıysa, foreign key'nin beklediğin users.id yerine başka bir tablo veya sütunu işaret edip etmediğini SHOW CREATE TABLE orders çıktısından kontrol et.
INSERT yerine UPDATE yaparken de foreign key hatası alabilir miyim?
Evet. Var olan bir child kaydın foreign key alanını parent tabloda karşılığı olmayan bir değere değiştiren UPDATE işlemi, MySQL'de foreign key denetimi kapsamında reddedilebilir.
Şema uyumsuzluğunu eksik parent kayıttan nasıl ayırabilirim?
İlk olarak sorguda kullandığın değerle parent kaydı SELECT ile ara. Sonuç yoksa eksik parent kaydı bir veri sorunudur. Sonuç varsa iki tablonun SHOW CREATE TABLE çıktısını karşılaştırarak foreign key hedefini ve sütun özelliklerini incele; bu ise şema kontrolüdür.
Önce değeri, sonra parent kaydı, en son ilişki tanımını denetlersen bu hatayı daha hızlı ve sistematik biçimde çözebilirsin.