Döngü Kurmadan Listeleme

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
ademcicek
Üye
Mesajlar: 409
Kayıt: 03 Eki 2003 01:50
Konum: Ankara

Döngü Kurmadan Listeleme

Mesaj gönderen ademcicek »

Herkese merhaba.Firebird veritabanı kullanıyorum.benim 2 tablom var.bir Abone Tablom birde Fatura tablom.abone tablosundan aboneleri alıyorum ve fatura tablosunun içinde arama yaptırıyorum.faturasını ödememiş kişileri buluyorum.eğerki kişinin 3 den fazla ödenmemiş faturası varsa kara listeye aldırmaya çalışıyom.listeyide memory tableye kayıt ediyorum. yalnız kayıtlar çok fazla galiba.ondan kaynaklı 1 sat bekliyorum.gerçi hala sonucunu göremedim.bu kadar uzun süre işime gelmez diye.ben öncelikle yaptığım hata vermeden çalışan kodu göndereyim.

Kod: Tümünü seç

procedure TBorcluListesi.btnBorcluBulClick(Sender: TObject);
var
  AboneNo: Integer;
  Donem: string;
  DonemAsil: string;
  AdSoyad: string;
  i: Integer;
begin
  if Application.MessageBox('Borçlular Aranmaya başlanacak Eminmisiniz?', 'UYARI', MB_YESNO or
    MB_ICONWARNING or MB_DEFBUTTON2) = IDYES then
  begin

 MemData.Close;
  dataMain.Close;
  dataMain.SelectSQL.Clear;
  dataMain.SelectSQL.Add('SELECT DISTINCT(ADSOYAD),UID,ABONENO,DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 ORDER BY ABONENO');
  dataMain.Open;
    prg.Properties.Min := 0;
    prg.Properties.Max := dataMain.RecordCount;

    i := 0;

    while not dataMain.Eof do
    begin
      i := i + 1;
      if (dataMain.FieldByName('KIRACIAD').AsString = '') then
        AdSoyad := dataMain.FieldByName('KIRACIAD').AsString
      else
        AdSoyad := dataMain.FieldByName('EVSAHIPAD').AsString;

      AboneNo := dataMain.FieldByName('ABONENO').AsInteger;
      with DM.dataGenel do
      begin
        Close;
        SelectSQL.Clear;
  SelectSQL.Add('SELECT DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=' + IntToStr(AboneNo) + '');
  Open;
  Donem := '';
  DonemAsil := '';

  if DM.dataGenel.RecordCount >= 3 then
  begin

    while not DM.dataGenel.Eof do
    begin
      Donem := DM.dataGenel.FieldByName('DONEMAD').AsString;
      DonemAsil := Donem + ' ';
      DM.dataGenel.Next;
    end;
    MemData.Open;
          MemData.Insert;
          MemDataABONENO.AsInteger := dataMain.FieldByName('ABONENO').AsInteger;
          MemDataADSOYAD.AsString := AdSoyad;
          MemDataDONEMADLARI.AsString := DonemAsil;
    MemData.Post;
  end;

 end;
 prg.Position := i;
dataMain.Next;
end;
end;
end;
merak ettiğim şu:sql ile ödenmeyen dönem 3 e eşit ve büyük olanları fatura tablosunu kullanarak gösterebilirmiyim.eğer onu gösteremezsem gönderdiğim kodların hızlanmasını nasıl sağlayabilirim.

kolay gelsin.teşekür ederim.
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

koda şöyle bir gözattım.
join , group by ve having kullanılarak

Kod: Tümünü seç

 while not DM.dataGenel.Eof do 
satırına kadar olan kodları iptal etmek mümkün olabilir.

"yapıyı bozmadan daha hızlı hale getirebilir miyim?" derseniz kodları stored procedurlere taşıyabilirsiniz.

çok hızlı bir öneri isterseniz
her defasında

Kod: Tümünü seç

 Close; 
 SelectSQL.Clear; 
  SelectSQL.Add('SELECT DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=' + IntToStr(AboneNo) + ''); 
  Open; 
şeklinde bir kullanımdan kaçının. Bunun yerine döngüye girmeden önce

Kod: Tümünü seç

 DM.dataGenel.SelectSQL.Clear; 
  SelectSQL.Add('SELECT DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=:ABONENO'); 
...
...

with DM.dataGenel do 
begin 
        Close; 
        params[0].asstring :=  IntToStr(AboneNo);
       Open; 
şekline çevirerek parametreleri kullanmak bile size bayağı bir hız kazandıracaktır.

son olarak kullandığınız nesnelerin her hangi bir datasource ordanda dbgrid tarzı bileşenlerle bir alakası varsa hesaplamaya başlamadan önce disablecontrols diyerek bu özellikleri kapatmanızı şiddetle tavsiye ederim.
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
ademcicek
Üye
Mesajlar: 409
Kayıt: 03 Eki 2003 01:50
Konum: Ankara

Mesaj gönderen ademcicek »

Hocam cevabınız için çok teşekür ederim.sizin verdiğiniz cevabı incelerken sql de de hata yaptığımın farkına vardım.yada o zaman değiştirmişim.sizin değiniz şekilde yani parametre göndererek de

Kod: Tümünü seç

with Dm.DataGenel do
begin
close;
params[0].asinteger:=Aboneno;
open
end;
işlemide aynı hızda oluyor.yani bir hızlanma mevcut değil.

procedur kullanarak hızlandırabilirsiniz demişiniz.burada procedure nasıl kullannacam onun içinden çıkmadım.çünkü buradaki veriler sürekli değişiyor.ben sonuçları herhangi bir tabloya değil memory de tutuyorum.çünkü gün içerisinde o çıkan liste değişebilir.ve kullanıcı günde 30 defa aynı işlemi yapabilir.biraz daha aydınlatırsanız sevinirim. kolay gelsin.
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

procedure derken firebird içine yazdığımız stored procedurleri söylemek istemiştim.

stored procedure kullanarak geriye sadece ödenmemiş faturaları döndermeniz ve işlemin hızını artırmanız mümkün. şu an ki yapınızdan görsellik olarak tek farkı şu olur. progresbar kullanamazsınız.
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
ademcicek
Üye
Mesajlar: 409
Kayıt: 03 Eki 2003 01:50
Konum: Ankara

Mesaj gönderen ademcicek »

sadettin hocam anladım stored procedure dediğinizi.ama ben burada nasıl kullanacam hususunda biraz açarmısınız demiştim.yani şu işlemi.

Kod: Tümünü seç

 a=SELECT DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=:ABONENO

a>=3 büyük olanları göster.
ademcicek
Üye
Mesajlar: 409
Kayıt: 03 Eki 2003 01:50
Konum: Ankara

Mesaj gönderen ademcicek »

arkadaşlar şu procedure yazmama yardım edermisiniz.ilk defa deneyecem.
önce kayitsayisi dediğim yerden kayıt sayısı 3 veya daha büyükse dönem adını bir stringe alacam döngü kurup.örneğin yeni DönemAdı=200501,200502,200503 gibi.

Kod: Tümünü seç

CREATE PROCEDURE BORCLUBUL
(KayitSayisi INTEGER,
i INTEGER,
 YeniDonemAd  VARCHAR(50))
AS
BEGIN
 KayitSayisi=(SELECT COUNT(*) FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=:ABONENO);
if KayitSayisi=>3 then ;

for i=0 to kayitsayisi do
begin
YeniDonem=DonemAd ', '
end;

END

yardımcı olursanız sevinirim..
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

Kod: Tümünü seç

FOR SELECT DISTINCT(ADSOYAD),UID,ABONENO,DONEMAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 ORDER BY ABONENO
into :P_ADSOYAD,:P_UID,:P_ABONENO,:P_DONEMAD
DO
BEGIN

 
/*
      if (dataMain.FieldByName('KIRACIAD').AsString = '') then 
        AdSoyad := dataMain.FieldByName('KIRACIAD').AsString 
      else 
        AdSoyad := dataMain.FieldByName('EVSAHIPAD').AsString; 
BURATI ANLAMADIĞIMDAN DOLAYI ÇEVİREMEDİM
*/

FOR   SELECT COUNT(*),DONEMAD FROM FATURASU WHERE ODENDI=0 AND     BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0 AND ABONENO=:P_ABONENO
GROUP BY DONEMADI
HAVING COUNT(*)>3
INTO :P_SAYI,:P_DONEMAD

DO
BEGIN
  SUSPEND;
END


END


tam olarak yapının nasıl birşey olduğunu bilmediğim için buna benzer bir kod işinize yarayabilir.
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
ademcicek
Üye
Mesajlar: 409
Kayıt: 03 Eki 2003 01:50
Konum: Ankara

Mesaj gönderen ademcicek »

arkadaşlar hiç bir şeye gerek kalmadan sevgili saadettin arkaşımın yardımlarıyla konuyu şöyle bir sql yazarak çözdüm.

Kod: Tümünü seç

SELECT COUNT(*)as KayitSayisi,ABONENO,ADSOYAD FROM FATURASU WHERE ODENDI=0 AND BASILDI=0 AND OKUNDU=1 AND FATURAIPTAL=0
GROUP BY ABONENO,ADSOYAD
HAVING COUNT(*)>=3
teşekür ederim. bu da yukarıda yapmaya çalıştığım şeyi çok hızlı bir şekilde yapıyor.
herkese kolay gelsin[/quote]
Cevapla