yaş bilgisini güncelleme

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

yaş bilgisini güncelleme

Mesaj gönderen y.kulac »

s.a.

firebird 1.5 ile yaptığım bir projede kişilerin yaşını bir döngü ile güncellettiriyorum.

Kod: Tümünü seç

procedure TfrmIstatistik.BitBtn13Click(Sender: TObject);
var
TARIH,BUGUN:TDateTime;
    GUN1,AY1,YIL1,GUN2,AY2,YIL2:word;
    GUN,AY,YIL:integer;
begin
ibdataset1.Open;
ibdataset1.First;
ibdataset1.FetchAll;
progressbar1.Max:= ibdataset1.RecordCount;
label97.Caption:= 'Yaş güncelleme sırasında lütfen bekleyiniz. Bu işlem kayıt sayınıza bağlı olarak zaman alabilir.';
Screen.Cursor := crHourGlass;
while not ibdataset1.Eof do
begin
BUGUN:=Date;

    TARIH:=ibdataset1DOGUMTARIHI.Value;
    DecodeDate(BUGUN, YIL1, AY1, GUN1);
    DecodeDate(TARIH, YIL2, AY2, GUN2);
    YIL:=YIL1 - YIL2;
    AY:=AY1 - AY2;
    if AY<0 then
    begin
       AY:=AY+12;
         YIL:=YIL-1;
    end;
    GUN:=GUN1 - GUN2;
    if GUN<0 then
    begin
       GUN:=GUN+30;
         AY:=AY-1;
    end;
    if AY<0 then
    begin
       AY:=AY+12;
         YIL:=YIL-1;
    end;
    ibdataset1.Edit;
    ibdataset1YAS.Value:=YIL;
    ibdataset1.Post;
    application.ProcessMessages;
 ibdataset1.Next;
progressbar1.Position:= ibdataset1.RecNo;
end;
progressbar1.Max:= 0;
label97.Caption:= 'Yaş güncelleme işlemi bitti.';
Screen.Cursor := crDefault;
label179.Caption:= '';
end;
4000 tane kayıt var. yaş güncelleme butonuna basınca 4000 adet kayıt için yaş hesaplaması yaklaşık 5 dakika alıyor. ileride kayıt sayısı 30.000 gibi bir rakam olursa bu belkide yarım saatten fazla bir zaman alacak.

acaba yukarıdai kodlarda bir hata veya mantıksızlık var mı?.
bu süreyi en minumuma nasıl indirebilirim.
iyi çalışmalar.
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7603
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

Merhaba,

Hata fetchall'da hocam, 4.000 kayıdın hepsini client'a çekiyorsun. Bir SP yap, DB tarafında hesaplasın.

Hesaba detaylı gözatmadım ama doğrulamasını yapınca sonuç istediğin gibiyse tamamdır : ) Yaş hesabı çok çetrefilli bir konu :D

Kolay gelsin.
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Mesaj gönderen aslangeri »

s.a.
yaşı calc alan olarak kullansanız nasıl olur.
geçen forumda geçmişti bu konu. aratırsanız ordan faydalanabilirsiniz.
kolay gelsin.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

mussimsek yazdı:Merhaba,

Hata fetchall'da hocam, 4.000 kayıdın hepsini client'a çekiyorsun. Bir SP yap, DB tarafında hesaplasın.

Hesaba detaylı gözatmadım ama doğrulamasını yapınca sonuç istediğin gibiyse tamamdır : ) Yaş hesabı çok çetrefilli bir konu :D

Kolay gelsin.
abi fetchall'ı bir kere yapıyorum. bunun sebebide
progressbar1.Max:= ibdataset1.RecordCount; için
döngü içinde fetchall yapmadım. hesap doğru. yani yaşı hesaplıyor.
sıkıntı bu işin zaman alması.
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Döngüden (while not eof) önce (mesela Open'dan sonra):

Kod: Tümünü seç

ibdataset1.DisableControls;
Döngüden sonra da:

Kod: Tümünü seç

ibdataset1.EnableControls;
diyerek tekrar test eder misin?

İyi çalışmalar.
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7603
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

y.kulac yazdı:...
abi fetchall'ı bir kere yapıyorum. bunun sebebide
progressbar1.Max:= ibdataset1.RecordCount; için
döngü içinde fetchall yapmadım. hesap doğru. yani yaşı hesaplıyor.
sıkıntı bu işin zaman alması.
hocam yazım olarak bir yanlış yok zaten. Yöntem hatası var.

@aslangeri gibi ben de olsa calculated alan kullanırdım. firebird'te bu seçenek var.

Ama yönteminize devam etmek istiyorsanız da SP ile yapmanızda aşırı fayda var. Fahrettin abinin seminerlerini izlemekte fayda var.

Kolay gelsin.
Kullanıcı avatarı
hbahadir
Kıdemli Üye
Mesajlar: 544
Kayıt: 06 Ara 2004 05:03
Konum: BURSA idi artık İST.
İletişim:

Mesaj gönderen hbahadir »

Kod: Tümünü seç

select count(*) from KUTUK 
ile progress barın için kayıt adedini alabilirsin. Artı @mussimsek ile aynı fikirdeyim.
abi fetchall'ı bir kere yapıyorum. bunun sebebide
progressbar1.Max:= ibdataset1.RecordCount; için
döngü içinde fetchall yapmadım. hesap doğru. yani yaşı hesaplıyor.
sıkıntı bu işin zaman alması.
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

Kod: Tümünü seç

ibquery1.Close;
ibquery1.SQL.Clear;
ibquery1.SQL.Add('select count(*) from BILGILER');
ibquery1.Open;
progressbar1.Max:= ibquery1.RecordCount;
hocam bu şekilde 4000 adet kayıt olan bir tablodan dönen toplam kişi sayısı =1 kişi

Kod: Tümünü seç

ibquery1.SQL.Add('select count(*) from BILGILER');
bu şekilde tam kişi sayısını vermediği gibi 1 gibi komik bir değer dönüyor. :?
Kullanıcı avatarı
hbahadir
Kıdemli Üye
Mesajlar: 544
Kayıt: 06 Ara 2004 05:03
Konum: BURSA idi artık İST.
İletişim:

Mesaj gönderen hbahadir »

şöyle yapabilirsin.
Progressbar1.max := ibquery1.Fields[0].AsInteger;
ek olarak formda count kullanımı üzerine arama yapsaydın bir sürü sonuç dönerdi.
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Fazla kafanı karıştırma istersen.

Fetchall, SQL vs. ilerde öğrenirsin.

Şimdiki sorunun bunlarla ilgili değil. Zira 4000 kaydı Fetchall yapmak 1-2 saniye sürmez. Sorunun döngüde, her kayıt sonrası ekranın update edilmesi ile ilgili.

Yoksa değil 4000 kayıt 4 milyon kaydın Fetchall işlemi 5 dakika sürmez.

Sen DisableControls ve EnableControls'ü önce dene. Eğer düzelmezse (ki büyük bir ihtimalle 5 dakikadan 3-5 saniyeye inecek) kullandığın datasetin eventlerine bakmak gerekecek.

İyi çalışmalar.
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7603
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

Aslında SP yapsan progressbar'a da gerek kalmayacak :D
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Mesaj gönderen Lost Soul »

bence sorunun

Kod: Tümünü seç

ibdataset1YAS.Value:=YIL; 
1. kayıta tablodan erişmek yerine ibdataset1YAS isminde TField tipinde bir değişken ile erişmişsin.
2. ibdataset1YAS.Value:=YIL; diyerek Asinteger yerine Variant değişken kullanmış oldun. Bu da her seferinde değişken tipine delphinin kendisinin kara vemesi demek

Ayrıca yılı hesplamak için o kadar hesap kitaba gerek yoktu.
zira delphide tarih ve saat aslında kayannoktalı sayının virgülden öncesi ve virgülden sonrasından başkası değil :D
yani
Trunc(DateTime);
ile noktadan önceki kısmını (Tdate) yani günsaysını

Frac(AValue); ile de noktadan sonraki kısmını (ttime) yani milisaniyeleri alabilirsin

dolayısı ile

Kod: Tümünü seç

yas:=(trunc(now) -trunc(dogumtarihi)) div 365 
yeterli.

bir diğer nokta ise
progressbar kullanmak istiyorsan

Kod: Tümünü seç

TDataset.Last;

dedikten sonra

Kod: Tümünü seç

PRogressbar1.max:=TDataset.recordcount
ve

Kod: Tümünü seç

progressbar1.postition:=tdataset.recno;
application.proceesmessages;
işlemin başında ve sonunda enablecontrols ve disablcontrols demeyi ihmal etme

ayrıca
gerek programda gerekse veritabanında beforeinsert,afterinser,beforepost,afterpost olaylarında kod olmadığından emin ol.

son olarak bunlar bi tarafa

Kod: Tümünü seç

yas:=(trunc(now) -trunc(dogumtarihi)) div 365 
benzeri bir fonksiyon SQL içinde mutlaka vardır. Gecenin 4 ü olduğ için o kadarını söyleyecek kadar kafam iyi değil :D

bu kodu bulup firebirdin kendi içinden tek satırda 1 saniyenin çok küçük bir parçası kadar bir süre içinde 4000 değil 40000 tane kaydı değiştirebilirsin.

Aklımagelenler şimdilik bunlar
Dediğim gibi gecenin 4 ünde yazıyorum. Bazen ekranı görmmekte güçlük çekiyorum :D:D
Cevapla