Foreign Key Kısıtlaması: Referanslar Olmadan Silme Neden Başarısız

Bir tablodan veri silmek istediğinizde "Foreign Key constraint" hatası alıyorsunuz. Bunun nedeni başka bir tabloda bu veriye referans veren kayıtlar var demektir. Veritabanı, yetim kayıtlar (orphaned records) oluşmasını engellemeye çalışıyor.

Örneğin, bir müşteri silmek istiyorsunuz ama o müşteriye ait siparişler hala var. Sistem bunu engeller.

Foreign Key, iki tablayı bağlar. Ana tablo (parent) ve referans tablosu (child). Eğer ana tablodan veri silerseniz, referans tablosundaki ilişkili kayıtlar "boşta" kalır. Bu veri bütünlüğünü bozar.

Önce tabloları oluşturalım:

1CREATE TABLE Musteriler (
2MusteriID INT PRIMARY KEY,
3Ad VARCHAR(50)
4);
5
6CREATE TABLE Siparisler (
7SiparisID INT PRIMARY KEY,
8MusteriID INT,
9Urun VARCHAR(50),
10FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
11);

Veri ekleyelim:

1INSERT INTO Musteriler VALUES (1, 'Ahmet');
2INSERT INTO Siparisler VALUES (101, 1, 'Laptop');

Şimdi müşteri silmeye çalışalım:

1DELETE FROM Musteriler WHERE MusteriID = 1;

Hata:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1Foreign Key constraint failed

Üç yol vardır:

1. Önce referans kayıtları silin:

1DELETE FROM Siparisler WHERE MusteriID = 1;
2DELETE FROM Musteriler WHERE MusteriID = 1;

2. Cascade Delete kullanın (tablo oluştururken):

1CREATE TABLE Siparisler (
2SiparisID INT PRIMARY KEY,
3MusteriID INT,
4Urun VARCHAR(50),
5FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
6ON DELETE CASCADE
7);

Bu durumda müşteri silinince siparişleri de otomatik silinir.

3. NULL değer atayın:

1UPDATE Siparisler SET MusteriID = NULL WHERE MusteriID = 1;
2DELETE FROM Musteriler WHERE MusteriID = 1;

Foreign Key, veri tutarlılığını sağlar. Silme işlemi başarısız olursa, önce referans kayıtlarını yönetin. Cascade Delete, sık silinen veriler için pratiktir ama dikkatli kullanın.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz
  • minikbirhesap

    yani kısaca önce ilişkili kayıtları silmen gerek sonra ana kaydı silebilirsin mesela müşteri silmek istiyorsan önce o müşterinin siparişlerini

  • adlı kullanıcıya yanıt verdi
    sokaklambasi

    ya da cascade set et siparişleri otomatik siler ya da null yapar daha pratik oluyor

  • adlı kullanıcıya yanıt verdi
    minikbirhesap

    cascade kullanmak işin kolay yolu ama dikkat etmek lazım yanlışlıkla silerken bağlı bütün

  • adlı kullanıcıya yanıt verdi
    sokaklambasi

    işte onda da risk var ya cascade açısam bir müşteri sildiğimde bütün siparişleri de gidiyor sonra fark ediyorum ne yaptığımı

  • adlı kullanıcıya yanıt verdi
    minikbirhesap

    işte bence cascade işin içini karmaşık hale getiriyor ben çoğu zaman soft delete yaparım yani kaydı gerçekten silmemek yerine silinmiş işareti koyarım