Malum veritabanı programlaması ile uğraşırken karşımıza çıkan sorunlardan birisi de zaman içerisinde veritabanında meydana gelen veya gelmesi kaçınılmaz olan değişiklikler ve bu değişiklikleri eski kullanıcılara sorun yaşamadan yansıtabilmektir.Exemizde yapmış olduğumuz değişiklikleri yada ek dosyalarımızdaki değişiklikleri yeni sürüm paketimize dahil ederek karşı bilgisayara kurulmasını sağlamak zor değildir.Ancak yeni setupımızda yeni ve değişik alanlar eklenmiş veritabanını koyamayız.Koysak ta bu programımızı ilk defa kuran kullanıcılar içindir.
(Bunu setup scriptleri ile ayarlamak zor değildir.Sanırım bu konuda da bir sıkıntı yok.Bunu setup programımızda eğer veritabanı dosyası varsa kurma, yok ise kur ve uninstall ayarlarında da database dosyasını asla kaldırma parametreleri ile ayarlarız.)Biz burada şunu yapmaya çalışacağız.Eğer setup programımız ile programımızı kuran kullanıcının bilgisayarında veritabanı mevcut değilse veritabanı dosyasını oluştur eğer varsa da mevcut dosyayı yeni dosya ya güncelleme olayıdır.Yine bu forumdan öğrendiğim mantıkla ben Firebird veritabanı kullandığım projelerimde şöyle bir metod kullanıyorum.Onu izah etmeye çalışacağım.
Öncelikle Veritabanı dosyamızın adı Data.FDB olsun.
Bu veritabanında bir adet DATAVERSION adında tablo açarız.Ve bu tabloda da VERSION diye bir alan açarız.Smallint tipinde.Veritabanı ilk oluşturulduğunda bu alanın değerini 1 yazarız.Yan, veritabanının 1.versiyon olduğunu teyit eden bir değer.
Sonra diyelim ki zaman içerisinde bu veritabanında bazı tablolar ekledik.Ya da bazı tablolara yeni alanlar ekledik.Yada bazı alanları silmek zorunda kaldık.Bu işlemlerin SQL kodlarını ise bir SQL uzantılı dosyaya kaydederiz.Mesela program dizinimiz içinde Update klasörü açar içinede Update2.SQL dosyasına kaydederiz.(Yani veritabanımızı 2.versiyona terfi ettirecek dosya anlamında)
Mesela aşağıda örnek bir SQL güncelleme kodu var.(Bu kodları IBExpertten tablonun DDL kodunu alarak yada tabloları yada alanları oluştururken IBExpert zaten bunların SQL kodlarını göstermektedir.)Programımı ilk yazdığımda UCRETLER tablosu yokmuş bu tabloyu sonradan eklemişim.Ama mevcut kullanıcıların veritabanlarında böyle bir tablo yok.Yeni veritabanını kuramazlar.Çünkü eski kayıtlarını nasıl kullanırlar o zaman.Yeni exeyide bu şekilde kurarlarsa veritabanı ile exe arasında uyumsuzluk olacaktır.Ucretler tablosunun SQL kodunu IBExpertten aldım.
Kod: Tümünü seç
/******************************************************************************/
/**** ****/
/**** Bu Script Veritabanı versiyonu 1 olan veritabanını ****/
/**** Son Versiyona Günceller.Yani Veritabanı 1.Sürüm Olan ****/
/**** Kullanıcının Veritabanı ile Son Versiyon Arasındaki ****/
/**** Farkları Kaldıran iki versiyonu birbirine ****/
/**** eşitleyen ayarları içerir. ****/
/******************************************************************************/
SET SQL DIALECT 3;
SET NAMES WIN1254;
/******************************************************************************/
/**** Tables ****/
/******************************************************************************/
CREATE TABLE UCRETLER (
KAYITID IDNO /* IDNO = NUMERIC(18,0) NOT NULL */,
MUSTERIKODU IDNO /* IDNO = NUMERIC(18,0) NOT NULL */,
ISLEMADI DMNAD /* DMNAD = VARCHAR(50) */,
BORC NUMERIC(15,2) DEFAULT 0,
ALACAK NUMERIC(15,2) DEFAULT 0,
TAHAKKUKTARIHI DATE,
VADETARIHI DATE
);
/******************************************************************************/
/**** Primary Keys ****/
/******************************************************************************/
ALTER TABLE UCRETLER ADD CONSTRAINT PK_UCRETLER PRIMARY KEY (KAYITID) USING INDEX PK_UCRETLER;
/******************************************************************************/
/**** Triggers ****/
/******************************************************************************/
SET TERM ^ ;
/******************************************************************************/
/**** Triggers for tables ****/
/******************************************************************************/
/* Trigger: UCRETLERCHNG */
CREATE TRIGGER UCRETLERCHNG FOR UCRETLER
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0
AS
begin
post_event 'UCRETLERDEGISTI';
end
^
SET TERM ; ^
/******************************************************************************/
/**** Privileges ****/
/******************************************************************************/
CREATE GENERATOR GNUCRETLERID;
/******************************************************************************/
/**** Privileges ****/
/******************************************************************************/
/******************************************************************************/
/**** ****/
/**** Bu Script Veritabanı versiyonu 1 olan veritabanını ****/
/**** Son Versiyona Günceller.Yani Veritabanı 1.Sürüm Olan ****/
/**** Kullanıcının Veritabanı ile Son Versiyon Arasındaki ****/
/**** Farkları Kaldıran iki versiyonu birbirine ****/
/**** eşitleyen ayarları içerir. ****/
/******************************************************************************/
Sonra ise exenizin kodlarının içine veritabanı tablolarınıza bağlanmadan önce sadece veritabanınızdaki DATAVERSION adlı tabloya bağlanarak VERSION alanının değer, kontrol edilir.Eğer 2 ise hiçbirşey yapılmadan diğer tablolara da bağlanılmasına izin verilir.
Ama eğer 1 ise Update \ Update2.SQL script dosyası çalıştırılır.bu script dosyası veritabanını yeni veritabanına günceller.Script dosyasındaki ekleme-silme-düzenlemeleri yapar.Bu işlemin ardından ise DATAVERSION tablosundaki VERSION alanının değeri 2 yapılır.
Bu SQL scriptlerini çalıştırmak içinde Delhi 2005 ve sonrasında InterbaseAdmin sekmesinde bulunan IBScript componenti ile yapıyorum.Delphi 7 de bu component bulunmamaktadır.Ancak interbase bileşenlerini güncellerseniz component palette görebilirsiniz.
Kod: Tümünü seç
Var dbversionno:integer;
dbversionno:integer :=DM.datasetDATAVERSION.FieldbyName(‘VERSION’).asinteger;
case dbversionno of
1: veritabanınıguncelle2;//Bu oluşturduğumuz procedur
2:veritabanınıguncelle3 ; Bu oluşturduğumuz procedur
3:veritabanınıguncelle4 ; Bu oluşturduğumuz procedur
4:veritabanınıguncelle5 ; Bu oluşturduğumuz procedur
………………………..
………………………..
………………………..
………………………..
end;
VeritabaniniGuncelle 2, VeritabaniniGuncelle 3, VeritabaniniGuncelle 4, procedurlerinida aşağıdaki gibi oluşturabiliriz.
Kod: Tümünü seç
procedure TDM.VeritabaniniGuncelle2;
begin
//************************************************************
IBScript1.Script.Clear;
IBScript1.Script.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Update\ Update 2.SQL');
IBScript1.ExecuteScript;
//************************************************************
//************************************************************
DatabaseVersiyonTable.Edit;
DatabaseVersiyonTable.FieldByName('DATAVERSION').AsInteger := 2;
DatabaseVersiyonTable.Post;
DatabaseVersiyonTransaction.CommitRetaining;
end;
Bu döngü bu şekilde halledilir.Tabi burada dikkat edilmesi gereken nokta şudur.veritabanı versiyonları arttıkça bunları güncelleyecek olan script dosyaları dikkatli oluşturulmak zorundadır.Yani versiyonu 1 olan veritabanını 5 nolu versiyona yükseltecek olan SQL scripti ile 3 nolu versiyonu 5 e yükseltecek olan script dosyası haliyle aynı olamayacağından bu konuda ben şöyle bir yol izliyorum.her versiyonda yapılan değişklikleri ayrı SQL dosyalarına kaydedip güncelleme yaparkende eğer mevcut database versiyonu 1 ise önce 2 ye sonra 2 yi 3 e, sonra 3 ü 4 e, sonrada 4 ü 5 e güncelleyen procedurleri çalıştırıyorum.
Eğer mevcut veritabanı versiyonuda 3 ise o na da 3 ü 4 e, sonrada 4 ü 5 e güncelleyen procedurleri çalıştırıyorum.
Bu şekilde hata olasılığı azalıyor.
Bu kod blokları çalıştıktan sonra ise program dosyanızın(EXE) diğer tablolara bağlanmasına izin verebiliriz.
Bu sistemi yaklaşık 1-1,5 yıldır kullanıyorum.İlk başlarken 1 olan veritabanı versiyonu şu an için 8.Hiç bir şekilde bir sorun yaşamadım.Son derece stabil ve güzel ve basit mantıklı ama bir o kadarda iş gören bir yöntem.Ancak anlatımımdan kaynaklanan anlaşılamayan hususlar olursa da soru cevaplarla topik olgunlaşır kanaatindeyim.
Uzun zamandır işlerin yoğunluğundan foruma pek bir katkımız olmamaktaydı.
Belki bu vesileyle bu konuda sıkıntısı olan arkadaşlara bir nebzede faydamız olursa ne mutlu bize.
Herkese kolay gelsin.