while not ve out of memory hatası

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
kayipgemi
Üye
Mesajlar: 88
Kayıt: 14 Kas 2005 03:07

while not ve out of memory hatası

Mesaj gönderen kayipgemi »

arkadaslar kolay gelsin bir sorum olacak yardımcı olabilirseniz sevinirim.
delphi7, sqlserver2005 - P4 3.0 cpu 3GB Rem bellek kullanıyorum
bir veritabanımızdaki bir tabloda yaklasık 30.000 den fazla kayıt var
ve kodumuz şu şekilde

Kod: Tümünü seç

    while not dm.Query.Eof do
    begin
    // yapılandırma kontrolunu baslat
    dm.kontrol.Close;
    dm.kontrol.SQL.Clear;
    dm.kontrol.SQL.Add('select count(*) from tblesnyaptra t where t.YAPKOD='''+dm.QueryYAPKOD.AsString+'''');
    dm.kontrol.Open;
      if dm.kontrol.Fields[0].AsInteger = 0 then
      begin
      cxSplitter1.OpenSplitter;
      RzMemo1.Lines.Add(dm.QueryYAPKOD.AsString+'-'+dm.QueryYPLNDRSTOKKOD.AsString+' Yapılandırma Detayı Yok');
      end;
    dm.Query.Next;
    cxGrid1.Refresh;
    end;
kayıtların arasında dolasmaya baslıyor bizde bu arada windowsun task maneger ini actık programımızın rem kullanımına bakıyoruz program ılk calistıgında 12 mb lik bir kullanım var ve while calismaya devam ettiği sürece rem kullanımımız 150 mb a kadar yavas yavas cıkıyor ve 150 mb üzerine cıkınca pat diye bir hata out of memory hatası alıyorum ama kayıtları filitrelersem ve sistem 150 mb tın üzerine cıkmadığı sürece bir sorun yok .. benim süzme yapmadan bütün kayıtları while ile okumam gerekiyor :( .. bana yardımcı olabilirseniz cok sevinirim bu hatayı nasıl giderebilirim.
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Mesaj gönderen Battosai »

Kullandığınız kod zaten yanlış tasarlanmış...Döngü içerisinde aynı datasete'e sorgu yaptırmak döngünün bozulması manasına gelecektir...olması gereken ilk önce sorgu yapıp sonra dönen sonuçları döngüye sokup istediğinizi yapmanızdır...Normal kullanım şekli aşağıdaki gibidir...

Kod: Tümünü seç

    dm.kontrol.Close;
    dm.kontrol.SQL.Clear;
    dm.kontrol.SQL.Add('select count(*) from tblesnyaptra t where t.YAPKOD='''+dm.QueryYAPKOD.AsString+'''');
    dm.kontrol.Open;
    dm.first;
    while not dm.Query.Eof do
    begin
      if dm.kontrol.Fields[0].AsInteger = 0 then
      begin
      cxSplitter1.OpenSplitter;       RzMemo1.Lines.Add(dm.QueryYAPKOD.AsString+'-'+dm.QueryYPLNDRSTOKKOD.AsString+' Yapılandırma Detayı Yok');
      end;
    dm.Query.Next;
    end; 
kayipgemi
Üye
Mesajlar: 88
Kayıt: 14 Kas 2005 03:07

Mesaj gönderen kayipgemi »

ilgin tesekkurler kardes ama sanırım kod blogu tam anlasılmamıs söyle izah edeyim

Kod: Tümünü seç

    dm.kontrol.Close; 
    dm.kontrol.SQL.Clear; 
    dm.kontrol.SQL.Add('select count(*) from tblesnyaptra t where t.YAPKOD='''+dm.QueryYAPKOD.AsString+''''); 
    dm.kontrol.Open; // burda querydeki ilk satırdaki bilgiyi aldın sorgulama yaptın
    dm.first; 
    while not dm.Query.Eof do // daha sonra burda queryi donguye soktun
    begin 
      if dm.kontrol.Fields[0].AsInteger = 0 then //yukarıdaki bilgiyi sart a baglı degerlendirdin
      begin 
      cxSplitter1.OpenSplitter;       RzMemo1.Lines.Add(dm.QueryYAPKOD.AsString+'-'+dm.QueryYPLNDRSTOKKOD.AsString+' Yapılandırma Detayı Yok'); 
      end; 
    dm.Query.Next; // daha sonra bur dan devam et dedin
    end;
sanırım kardeş dikkatinden kacmıs while arasındaki senin tabirinle hep ilk satırı donderiyoruz, bu kodla hep ilk satırdaki bilgiyi donderir, (emin olamak için denedim hep ilk satırı dönderiyorda) yapmak istediğim şu 30.000 kayıt ı olan bir tablonun içerisine girip ilksatırı okuyup burdaki bilgilere dayalı olarak baska bir tablodan bilgi cekip degeri kosul a gore memo nun içine yazdırmak daha sonra ikinci satıra ve daha sonra son kayıt a kadar bu ıslemı devam ettırmek, bunu sağlıyorum ama memory hatası alıyorum bunu nasıl çözebilirim, yinede ilgin için teşekkürler sağolasın
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Mesaj gönderen aslangeri »

s.a.
cxgridi refresh etmeseniz nasıl olur. gerçi ikinci kod bloğunda görünmüyor ama ondan kaynaklanıyor olabilir.
iyi çalışmalar.
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
Kullanıcı avatarı
conari
Üye
Mesajlar: 2102
Kayıt: 27 Nis 2006 03:10
Konum: İstanbul & Gebze Karışık

Mesaj gönderen conari »

Kulağımızı tersten tutuyormuşuz gibi geldi bana.

Kod: Tümünü seç

dm.kontrol.Fields[0].AsInteger = 0 then 

Şartını Query koysak kayıtları kıssak olmazmı?
"benim süzme yapmadan bütün kayıtları while ile okumam gerekiyor "
Demişsiniz iki farklı sorgu kullanın veya Memtable deneyebilirsiniz gibime geliyor.
Bir kelimenin anlamını öğretsen bile yeter..
ResimResim
kayipgemi
Üye
Mesajlar: 88
Kayıt: 14 Kas 2005 03:07

Mesaj gönderen kayipgemi »

Resim

hata resmi üste

arkadaşlar ilginize gereçekten cok teşşekkür ederim
aslengeri kardeşim : dediğini uyguladım ama grid ile alakalı değil yine rem 150 mb a ulaştıgında hatayı veriyor

conari kardeşim : dediğinizi uyguladım sql data acses (SDAC)bileşenin de virtual table var memtable ile aynı işi yapıyor ve uyguladım ama yine rem kullanımı 150 mb a cıkınca yine out of memory hatasını alıyorum ..

sizde atkdir edersinizki buyuk bir uretim yapan ve ERP sistemi kullanan bir fabrikadaki üretilen ürünlerin reçeteleri ve stok kodları ve yapılandırma kodları cok fazladır ve kullanıcıların bu kartları reçeteleri oluştururken hata yapıp yapmadıklarını tespit etmeniz gerekir ki üretim hatalı olmasın .. bu projede hata kontrolu yapmaya calisiyorum ama ne yazıkki rem kullanımına baglı olarak bu hatayı almaya devam ediyorum istersiniz size kod blogunun hepsini gonderemeyim bir de oyle bakalım olurmu

Kod: Tümünü seç

begin
cbekleac;
kontrolbtn.Down := true;
RzMemo1.Clear;
  if dm.Connection.Connected = false then
  begin
  veritabaninabaglanBtn.Click;
  end
  else
  begin
    dm.Query.First;
    RzMemo1.Lines.Clear;
    Gauge1.Progress   := 0;
    Gauge1.MaxValue   := dm.Query.RecordCount;

    while not dm.Query.Eof do
    begin
    // yapılandırma kontrolunu baslat
    dm.kontrol.Close;
    dm.kontrol.SQL.Clear;
    dm.kontrol.SQL.Add('select count(*) from tblesnyaptra t where t.YAPKOD='''+dm.QueryYAPKOD.AsString+'''');
    dm.kontrol.Open;
      if dm.kontrol.Fields[0].AsInteger = 0 then
      begin
      cxSplitter1.OpenSplitter;
      RzMemo1.Lines.Add(dm.QueryYAPKOD.AsString+'-'+dm.QueryYPLNDRSTOKKOD.AsString+' Yapılandırma Detayı Yok');
      end;
    // yapılandırma kontorlu bitti

    // reçecete kontolune baslat
    dm.kontrol.Close;
    dm.kontrol.SQL.Clear;
    dm.kontrol.SQL.Add('select count(*) from tblstokurm s where s.MAMYAPKOD='''+dm.QueryYAPKOD.AsString+''' and s.MAMUL_KODU='''+dm.QueryYPLNDRSTOKKOD.AsString+'''');
    dm.kontrol.Open;
      if dm.kontrol.Fields[0].AsInteger = 0 then
      begin
      cxSplitter1.OpenSplitter;
      RzMemo1.Lines.Add(dm.QueryYAPKOD.AsString+'-'+dm.QueryYPLNDRSTOKKOD.AsString+' Reçete Detayı Yok');
      end;
    // reçecete kontolune bitti

    dm.Query.Next;
    cxGrid1.Refresh;
    Gauge1.Progress := cxGrid1DBTableView1.DataController.DataSet.RecNo;
    end;
    if RzMemo1.Text = '' then
    begin
    Application.MessageBox('Yapılandırma ve Reçete Kontorlu Yapıldı'#13'Hata Yok','Sistem Uyarı',MB_OK+MB_ICONINFORMATION);
    Gauge1.Progress := 0;
    end
    else
    begin
    Application.MessageBox('Hatalar var Lütfen LOG Kayıtlarını Kontrol edin...!','Sistem Uyarı',MB_OK+MB_ICONWARNING);
    Gauge1.Progress := 0;    
    end;
    cbeklekapat;
  end;
end;
bana yardımcı olabilirseniz cok sevinicem hayırlı calismalar olsun ..
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Bence döngü içinde kayıt sayısı hesaplamayı kullanma, direk sorgu ile hesaplat. dm.Query sorgun nedir bilmiyorum ama select * from dm_Query olarak varsayıyorum. Sanırım alt tabloda kaç kayıt var gibisinden bir kontrole girmişsin. Bunu tek sorgu ile elde etmek mümkün.

Kod: Tümünü seç

select altkayitsayisi.KayitSay,dm_Query.* from dm_Query
left join

 (select ana.YAPKOD,KayitSay=count(ana.YAPKOD) from dm_Query as ana left join tblesnyaptra as alt on alt.YAPKOD=ana.YAPKOD group by ana.YAPKOD having count(ana.YAPKOD)>0)

 as altkayitsayisi on dm_Query.YAPKOD=altkayitsayisi.YAPKOD
gibi bir sorgu ile ana tabloya ait tüm satır bilgisi ile alt tabloda kaç kayıt var hepsini birden öğrenebilirsin. Bu değeri her satır için çalıştırmana gerek kalmayacağı için çok iyi derecede sistem kaynaklarından tasarruf edeceğini umuyorum.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Mesaj gönderen Battosai »

Sorgunu yap-> döngüye al->karşılaştır-> sonucu yaz. > fomül bu arkadaşım...Hata neden oluyor biliyormusun? SQlserver'a haddinden fazla yükleniyorsun döngü ile de ondan. Dolayısyla memory hatası verir...iki tablodaki değeri karşılaştırmak isityorsan bunu tek sorgu ile slqserver'yaptır sonra dönen değerleri istediğin yere yaz...join ile tablo birleştirme biliyorsan dataset'ini ona göre oluştur sonra anında sonuca ulaş...böyle yaparsan bu hatayı almaman mümkün değil...
kayipgemi
Üye
Mesajlar: 88
Kayıt: 14 Kas 2005 03:07

Mesaj gönderen kayipgemi »

cevaplarınız teşekkür ederim sağolun bu işi sizlerinde ongordugu gibi sql ile tabloları birleştirerek yapacagım sanırım join ile birleştirmeler yapatarak bir wiev oluşturup delphi içerisinden de bir procedure ile çözecegim, olmazsa artık cursor oluşturarak deneyecegim. server e cok yuklenecez anlasılan yorumlarınız için cok tesekkur ederim sağolun
Cevapla