Eyl 4
Digg
Stumbleupon
Technorati
Delicious

SQLite a Foreign Key desteği sağlamak

SQLite bildiğimiz gibi Foreign Key desteği yok buda bize veri bütünlüğünü sağlamada zorluklar yaşatmaktadır. Fakat bunuda yapayda olsa sağlamak mümkün. Trigger lar yardımıyla SQLite veritabanımıza Foreign Key desteği sağlatabiliriz. Örnek olarak 2 tablo oluşturuyoruz. Basit olarak 2 tablo birinde blog entry lerini tutacağız diğerindede kategorileri. Entry ve Category tablomuz arasında ir ilişki var fakat bunu SQLite tanımlayamıyoruz.


İlk olarak Entry tablosuna yeni bir kayıt eklendiğinde eklenilmeye çalışılan kategorinin Category tablosunda olup olmadığını kontrol edelim. Olmayan bir kategoriye ait entry eklemek istemeyiz heralde :) .  Yapmamız gereken tek şey sözle ifade ettiğimiz bu koşulu SQLite a bir INSERT TRIGGER ile belirtmek.
CREATE TRIGGER EntryInsertTrigger
BEFORE INSERT ON Entry
BEGIN
      SELECT CASE
           WHEN(SELECT CategoryID FROM Category WHERE CategoryID=NEW.CategoryID) IS NULL
           THEN RAISE(ABORT,'Eklemeye çalıştığınız kategori mevcut değil')
       END;
END;
Trigger ile Entry tablosuna bir kayıt eklenmeden hemen önce eklenmeye çalışılan CategoryID bir alt sorgu yardımıyla Category tablosunda olup olmadığı kontrol ediliyor. Eğer yoksa NULL döndürülüyor ve bir hata fırlatılıyor. Böylece Entry tablomuza olmayan bir kategoriye ait entry girişi yapılmasını engelledik. Ya UPDATE işlemi:
CREATE TRIGGER EntryUpdateTrigger
BEFORE UPDATE OF CategoryID ON Entry
BEGIN
      SELECT CASE
           WHEN(SELECT CategoryID FROM Category WHERE CategoryID=NEW.CategoryID) IS NULL
           THEN RAISE(ABORT,'Eklemeye çalıştığınız kategori mevcut değil')
       END;
END;
Evet sadece CategoryID güncellenmeye çalışıldığında devreye girecek bir trigger tanımlayıp INSERT trigger ında yaptığımız işlemi aynen tekrarlıyoruz. Son olarak bütünlüğü sağlamamız için bir şeye daha ihtiyacımız var. Entry tablosunda bir kaydın silinmesi Category tablosu üzerinde hiçbir etki göstermeyecektir ki zaten böyle birşey de istemiyoruz. Fakat ya Category tablosunda bir kayıt silinmeye çalışılırsa ne olacak. İşte eğer veri bütünlüğünü sağlamamışsak artık olmayan bir kategoriye ait entry lerimiz olacaktır. O zaman şöyle birşey yapsak. Category tablosundan bir kayıt silinirken o kategorinin Entry tablosunda kullanılıp kullanmadığına baksak zaten eğer kullanılmamışsa silip silmememiz bir anlam ifade etmeyecektir fakat mevcut bir kayıt varsa sorun çıkacaktır. Tam bu noktada devreye girip bizde sorunu çözeriz.
CREATE TRIGGER CategoryDeleteTrigger
BEFORE DELETE ON Category
BEGIN
      SELECT CASE
           WHEN(SELECT COUNT(CategoryID) FROM Entry WHERE CategoryID=OLD.CategoryID) > 0
           THEN RAISE(ABORT,'Silmeye çalıştığınız kategori Entry tablosunda mevcut.')
       END;
END;
ve işte bu kadar küçük, şirin, sevimli ve bi o kadarda hızlı veritabanımıza trigger tabanlı foreign key desteği sağladık.Hiçde zor değilmiş değil mi ? :D