Önce yukarıdaki gibi veritabanı kısmını hazırlayın. Her tablonun ilk alanını integer tipte otomatik artacak bir primary key li alan yapıyoruz. Bu alanların değerlerini sp kullanarak oluşturduğumuz generatordan alıyoruz. Sp kullanmamızın sebebi IBTable bileşeninde generator desteği olmamasıdır. İlçeler tablosundaki il_kodu alanını iller tablosundaki il_kodu alanına bağlı bir foreign key tanımlıyoruz. Semtler tablosundaki ilçe_kodu alanını ise ilçeler tablosundaki ilçe_kodu alanına bağlı bir foreign key oluşturuoruz. Böylece ilçeler tablosunda bir kayıt silindiği zaman semtler tablosunda ona bağlı alanlar silinecektir. İller tablosunda bir kayıt silindiği zaman ise önce ilçeler tablosundaki ilgili kayıtları silmeye gidecek ancak semtler tablosu ilçelere bağlı olduğu için önce semtler tablosunda ilçeler tablosuna bağlı kayıtlar silinir daha sonra ilçeler tablosundaki ilgili kayıtlar silinir. İller tablosu ilçeler tablosunu tetiklerken ilçeler tablosu da semtler tablosunu tetiklemektedir. Bu güncelleme içinde geçerlidir.
SP’deki kod ise sp ye delphiden tablo ismini parametre olarak alıp o parametreye bakarak hangi generatordan veriyi alacağığmızı belirliyoruz. Bunun master/detaille ilgisi yoktur. Siz bildiğiniz şekilde otomatik artan alanınızı oluşturabilirsiniz. Size örnek teşkil etmesi için bunu tercih ettim. Primary ve foreign keye sahip alanlar not null olmalıdır. Şimdi işlemin delphi kısmına geçebiliriz.
Şimdi hem IBTable hemde IBDatasetle Master / Detail bağlantıyı yapıcaz. IBQuery’de IBDataset gibidir. Projeye bir datamodule ekleyip üzerine 1 IBDatabase, 1 IBTransaction, IBStoredProc, 3 IBDataset, 3 IBTable, 6 DataSource Bileşeni ekleyin. IBDatabase ve IBTransaction ayarları yapın. IBStoredProc Bileşenine oluşturduğumuz SP'yi gösterin. Datamodule’nin görüntüsü aşağıdaki gibi olmalı.
görüntüde hangi bileşene hangi ismi verdiğimi görüyorsunuz. Her tabloyu kendi datasourcesine bağlayın.
Formunuza 6 dbgrid 6 dbnavigator ve her birinin datasource özelliklerini ayarlayın. Formun görüntüsü aşağıdaki gibi olabilir.
şimdi gelelim master/detail ilişkiye. IbDataset ile Master/Detail bağlantı kurmayı öğrenelim. Master tablomuz olan ve illeri listeleyen Qry_IL bileşeninin SelectSQL özelliğine bildiğiniz şekilde tabloyu listeletin. Bu özelliğe aşağıdaki SQL Sorgusunu ekliyoruz.
Kod: Tümünü seç
select * from TBL_IL
Kod: Tümünü seç
select * from TBL_ILCE Where IL_KODU=:IL_KODU
semtler tablosunu gösteren Qry_semt bileşeninin SQL Cümleside aşağıdaki gibidir.
Kod: Tümünü seç
select * from TBL_SEMT where ILCE_KODU=:ILCE_KODU
Şimdi detail tabloya kayıt girildiğinde siz master tablodaki aktif kaydın foreign keyin bağlı olduğu primary key alanının değerini foreign key tanımladığınız alana atamalısınız. Bunun için detail tabloların BeforePost olayına aşağıdaki kodu gibi bir yazmalısınız.
QRY_ILCE
Kod: Tümünü seç
if Qry_ILCE.FieldByName('IL_KODU').IsNull then //aLANDA DEĞER YOKSA
Qry_ILCE.FieldByName('IL_KODU').Value:=Qry_IL.FieldByName('I L_KODU').Value;
Kod: Tümünü seç
if Qry_Semt.FieldByName('ILCE_KODU').IsNull then //aLANDA DEĞER YOKSA
Qry_Semt.FieldByName('ILCE_KODU').Value:= Qry_Semt.FieldByName('ILCE_KODU’).Value;
Kod: Tümünü seç
if DataSet.Fields.Fields[1].IsNull then //ALANDA DEĞER YOKSA
DataSet.Fields.Fields[1].Value:=DataSet.DataSource.DataSet.Fields.Fields[0].Value;
Bunun dışında otomatik artan alanımızada kayıt eklenmeden önce değer atanmalıdır. Bunun içinde IBQueynin GeneratorField özelliğini daha önce anlattığım şekilde ayarlayın.
Bileşenlerin Active özelliklerini True yapıp test edebilirsiniz. Bu arada yukarıdaki semtler tablosunda semt_adi alanı integer değil varchar olacak.
Şimdi gelelim IBTable bileşenleriyle Master / Detail bağantıya. Burada da ilişki mantığı aynıdır. Bağlantıya geçmeden önce tablonun BeforePost olayında yapacağımız atamaları yapalım. Detaildeki Foreign key’li alana değer atamak dışında IBTablenin GeneratorField özelliği olmadığı için beforePost olayında sp aracılığıyla Generatordan değeri alıp ilgili alana atamalıyız. 3 tabloyu seçerek aşağıdaki ortakkodu BeforePost olayına yazıyoruz.
Kod: Tümünü seç
IF DataSet.Fields.Fields[0].IsNull then
Begin
SP_GEN.Params.ParamByName('TABLO_ADI').Value :=UpperCase(DataSet.Name);
SP_GEN.ExecProc;
DataSet.Fields.Fields[0].Value:=SP_GEN.Params.ParamByName('GEN_NO').Value;
end;
if UpperCase(DataSet.Name)<>'TBL_IL' then
if DataSet.Fields.Fields[1].IsNull then //ALANDA DEĞER YOKSA
DataSet.Fields.Fields[1].Value:=DataSet.DataSource.DataSet.Fields.Fields[0].Value;
Dikkat ederseniz Detail datbloya değer atamadan önce datasetin master tablo olup olmadığı kontrol ediliyor. Maser Tablo ise işlem yapılmıyor.
IbTabledede Master tabloda bir farklılık yok. Normal bağlantıya dokunmayın. İlçeler tablosunu illere bağlamak içinse TBL_ILCE bileşenini seçip MasterSource özelliğinden iller tablosunu listeleyen DataSourceyi seçin. Alan bağlantılarını yapmak içinse yine tbl_ilce tablosunu seçip MasterFields özelliğini tıklayın. Bağlantıyı oluşturmak için aşağıdaki pencere karşınıza çıkacaktır.
ilişkiyi kurup OK’e tıklayın.
TBL_Semt bileşenini seçip MasterSource özelliğinden ilçeler tablosunu listeleyen DataSourceyi seçin. Alan bağlantılarını yapmak içinse yine tbl_semt tablosunu seçip MasterFields özelliğini tıklayın. Bağlantıyı oluşturmak için aşağıdaki ayarları yapın.
örnek uygulamayı çalıştırıp test edebilirsiniz.
Bu örnekteki semtler tablosunu iller tablosuna bağlamak isteseydik DataSource,Parametre veya MasterSource, MasterFields özelliklerini iller tablosuna göre ayarlamalıydık. Veritabanı kısmında ise foreign keyi ilçeler tablosuna değil iller tablosuyla ilişkilendirmeliydik.