none
Bakiye Güncelleme İşlemi RRS feed

  • Soru

  • Tarih,Alacak,Borç,Bakiye Tablosu Var Kulandığım Veritabnı Mysql  Mantık Şu

    Tarih 01-03-2019  Alacak 100,00  Borc 0  Bakiye -100,00

    Tarih 01-03-2019  Alacak 0  Borc 150  Bakiye 50,00

    Tarih 02-03-2019  Alacak 200,00  Borc 0  Bakiye -150,00

    Tarih 03-03-2019  Alacak 50,00  Borc 0  Bakiye -200,00

    Tarih 03-03-2019  Alacak 0  Borc 450,00  Bakiye 200,00

    Tarih 04-03-2019  Alacak 0  Borc 150,00  Bakiye 350,00

    Tarih 05-03-2019  Alacak 0  Borc 50,00  Bakiye 400,00

    şimdi bu tabloda ben ayın ikisindeki veriyi sileceğim ve onun altındaki bakiyeler ona göre kendini otomatik güncelleyecek Beb Şöyle Bir şey geliştirdim

    IDCari.Clear();
                db.OpenConnection();
                String sorgu = "SELECT ch.ID FROM cari_hesap_tablo ch INNER JOIN anafatura_tablosu f ON f.ftrID = ch.ftrID WHERE cID ='" + KntlmID + "' AND f.ftrTarih >= '" + TarihKontrol.Value.ToString("yyyy-MM-dd") + "' AND f.FisDelete = 'Aktif' ORDER BY f.ftrTarih,f.ftrNo,ch.ID";
                cmd.CommandText = sorgu;
                cmd.Connection = ConnDB.baglanti;
                read = cmd.ExecuteReader();
                while (read.Read())
                {
                    IDCari.Add(read.GetInt32(0));
                }
                read.Close();
                db.CloseConnection();
                try
                {
                    db.OpenConnection();
                    String sorgu7 = "SELECT SUM(ch.borc),SUM(ch.alacak) FROM cari_hesap_tablo ch INNER JOIN anafatura_tablosu f ON f.ftrID = ch.ftrID WHERE cID = '" + KntlmID + "' AND f.ftrTarih < '" + TarihKontrol.Value.ToString("yyyy-MM-dd") + "'AND f.FisDelete = 'Aktif'";
                    cmd.Connection = ConnDB.baglanti;
                    cmd.CommandText = sorgu7;
                    read = cmd.ExecuteReader();
                    if (read.Read())
                    {
                        Borc = read.GetDecimal(0);
                        Alacak = read.GetDecimal(1);
                    }
                    read.Close();
                    db.CloseConnection();
                    Bkye = Borc - Alacak;
                }
                catch
                {
                    read.Close();
                    db.CloseConnection();
                    Bkye = 0;
                }
                foreach (int CID in IDCari)
                {
                    db.OpenConnection();
                    String sorgu1 = "SELECT borc, alacak FROM cari_hesap_tablo  WHERE ID = '" + CID + "'";
                    cmd.Connection = ConnDB.baglanti;
                    cmd.CommandText = sorgu1;
                    read = cmd.ExecuteReader();
                    if (read.Read())
                    {
                        Borc = read.GetDecimal(0);
                        Alacak = read.GetDecimal(1);
                    }
                    read.Close();
                    db.CloseConnection();
                    Bkye += Borc - Alacak;
                    cClas.UpdateYeniCariBakiye(Bkye, CID);
                }
                Bkye = 0;

    sildiğim tarih üstündeki bakiyeyi read edip silinen tarih de ki ve altındaki hesap IDlerini bir Liste Kaydediyorum sonra ona göre güncelleme yaptırıp kaydediyorum ama bu veriler artıkça güncelleme hızını yavaşlatır gecikme olur bunu nasıl daha basite indirgenebilir hızlandırabiliriz

     

    7 Mart 2019 Perşembe 08:47

Yanıtlar

  • SQL cümlelerinde bu sekilde + ... + gibi string birleştirerek sorgu yazılmaz, parametre kullanılır (o daha büyük bir hata, onun icin once onu yazdım - parametre kullanilmasinin nedeni sadece "SQL injection attack" önlemektedir degil, ayni zamanda o parametrelerin doğru islenmesini sağlamaktır. Ornegin yukarıda bir datetime degeri var, her ne kadar ISO 8601 benzeri kullandiginiz string calissa da, emniyetli olan parametre kullanmak).

    Ikincisi, yürüyen bakiye icin kalici ve güncellenmesi gereken bir kolon tutulmaz. Bu bilgi select sırasında hesaplanır (yoksa sizin yasadiginiz problem gibi, 10-15 milyon kaydın olduğu yerde 2.kayit silinir ya da değiştirilirse, 10-15 milyon satirin gereksiz yere güncellenmesi demektir). 

    MySQL 8 ve sonrası icin:

    select Tarih, Alacak, Borc,
    Sum(Borc-Alacak) over (order by tarih, borc) as Bakiye
    from tabloAdi;
    Daha eski MySQL versiyonlarında daha zahmetli de olsa UNBOUNDED preCEDING, CURRENT ROW ... kullanarak yapabilirsiniz (ya da postgreSQL, MariaDb ... kullanmayı düşünebilirsiniz). 

    7 Mart 2019 Perşembe 14:30
    Yanıtlayıcı