firebird de Yürüyen Bakiye ve CURSOR

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

merhaba;
Borç Alacak bakiye için aşağıdaki kodu kullanıyorum.

Kod: Tümünü seç

SELECT CH.ID, CH.CARIID, CH.HRKKOD, CH.MODULID, CH.MODULADI, CH.ISLEMADI, CH.EVRAKNO, CH.TARIH, CH.SAAT, CH.BORC, CH.ALACAK 
(SELECT (COALESCE(SUM(BORC),0)-COALESCE(SUM(ALACAK),0)) FROM TBLCARIHAR WHERE (TBLCARIHAR.CARIID=CH.CARIID) AND ((TBLCARIHAR.TARIH<CH.TARIH) OR (TBLCARIHAR.TARIH=CH.TARIH) AND (TBLCARIHAR.ID<=CH.ID))) as bakiye
FROM TBLCARIHAR as CH
WHERE (CH.CARIID=:CID) order by CH.TARIH
hareket sayısı 300-500 harekette kadar performans sorunu fazla yaşamıyorum. ancak daha fazlalaşınca yavaşlama oluyor. hareket sayısı 2000 -3000 olunca hareketlerin gelmesi çok sürüyor.

formda borç alacak bakiye konusunu araştırırken CURSOR denen bir mevzuyla karşılaştım. bildiğim bir konu değil daha önce hiç kullanmadım. yaptığım araştırmaya göre de yürüyen bakiye için verimli bir olay.

Firebird 2.5.2 versiyonunu kullanıyorum.
yukarıdaki kodu IBQUERY içinde kullanıyorum. Cursor olayı IBQUERY içinde bu kod ile kullanılabilinir mi,

konu ile ilgili dökümanı olan varsa paylaşırsa memnun olurum. değerli arkadaşlar konu ile ilgili temel düzeyde yardımlarınızı bekliyorum.

Teşekkür ederim.
İsteyen, yapabildiğinden daha fazlasını yapar.
akdatilla
Üye
Mesajlar: 292
Kayıt: 02 Nis 2006 06:04
Konum: Antalya

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akdatilla »

Evet bu işlemi bir sp içerisinde cursor kullanarak yapabilirsiniz. Önce istediğiniz çıktıyı verecek şekilde bir tablo açın. Cursor kullanırken tüm satırları bir döngü halinde işleyebileceksiniz, bu dögü içerisinde borc ve alacak toplam hesabını değişkenler kullanarak yapın. Değişkenlerde bulunan değerleri çıktı tablosuna kaydedin. Hazırladığınız tabloyu ekrana yada rapora dökebilirsiniz.
Çoklu kullanıcı ortamını düşünürsek çıktı olarak kullanılacak tabloya kullanıcı id'sini bir kolon olarak eklemeniz gerekir. Sorgulamayı da bu kullanıcı id'sine göre yapmalısınız.
Kolay gelsin.
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

merhaba
konuyla ilgili biraz araştırma yaptım. bulup kendime göre düzenlediğim kod kısaca aşağıdaki gibi,

Kod: Tümünü seç

EXECUTE BLOCK
RETURNS
( ID BIGINT,
  CARIID BIGINT, 
  BORC DOUBLE PRECISION,
  ALACAK DOUBLE PRECISION,
  BAKIYE DOUBLE PRECISION,
  DOVIZ VARCHAR(20),
  ACIKLAMA VARCHAR(300)
)
AS
DECLARE VARIABLE DYN_BAKIYE DOUBLE PRECISION;
BEGIN
  DYN_BAKIYE = 0.00;
  FOR
    SELECT ID,CARIID,BORC, ALACAK, DOVIZ, ACIKLAMA 
    FROM TBLCARIHAR WHERE (CARIID = :CARIID) AND (DOVIZ = :DOVIZ) Order By ID, TARIH
  INTO 
    :ID, :CARIID, :BORC, :ALACAK, :DOVIZ, :ACIKLAMA
  DO
  BEGIN
      DYN_BAKIYE = DYN_BAKIYE + BORC - ALACAK;
      BAKIYE = DYN_BAKIYE;
  SUSPEND;
  END
END;
Kod iyi çalışıyor. henüz tam olarak test etmedim ama. bu kodda prametre bölümünden sorun yaşıyorum.

Kod: Tümünü seç

WHERE (CARIID = :CARIID) AND (DOVIZ = :DOVIZ) 
delphi den fdquery e parametre değeri gönderdiğim zaman Argument Out Of Range hatası alıyorum. sabit değer verince bir sorun yaşamıyorum. kod çalışıyor. parametre gönderince söylediğim hatayı alıyorum. bu konuda yadımlarınızı bekliyorum.

teşekkür ederim
İsteyen, yapabildiğinden daha fazlasını yapar.
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen esistem »

Selam,
Yürüyen bakiye olayında rdb$set_context ve USER_TRANSACTION olayını araştırın, stored procedur e felan gerek kalmaz.
Aşağıda birebir kendi kullandığım SQL kodu bulunmaktadır. "Bakiy" field i yürüyen bakiyeyi verir. Kısaca önce #bky isminde bir değişken tanımlanıp ilk olarak sıfır'a "0" eşitleniyor, sonraki her satırda bunun üzerine borc eklenip alacak çıkartılıp tekrar set ediliyor, her satırda Bakiy değeri değişiyor.
Burada dikkat edilmesi gerekli husus ise şudur, BAKIYESIFIRLA isminde bir QUERY Cari hesap tablosundaki her hareket öncesi çalıştırılıyor ki #bky değişkeni Cari hesaplar gridinde her hareket edildiğinde sıfırlanabilsin. Kodu aşağıdadır.

Kod: Tümünü seç

SELECT rdb$set_context( 'USER_TRANSACTION' ,'bky#' ,0) from rdb$database;
Not:Bir blog da görmüştüm bu user_transaction olayını ama site adını hatırlamıyorum.
(Siteyi buldum : http://www.boreas.gen.tr/firebirde-yuru ... unning-sum)

Kod: Tümünü seç

SELECT I.KOD, I.CARIKODU, I.ISLEMTURU, I.ISLEMTURUALT, I.ISLEMKODU, I.TARIH, I.BORC, I.ALACAK, I.ACIKLAMA, I.BAYIKODU, I.KULKODU, I.FOYKODU, I.ACIKLAMA1, I.DOVIZKODU, I.KUR, I.FATMI, I.VADETARIHI, 
CASE
WHEN I.ISLEMTURU=0 THEN  'Devir Borç'
WHEN I.ISLEMTURU=1 THEN  'Devir Alacak'
WHEN I.ISLEMTURU=2 AND I.FATMI=1 THEN  'Satış Fat.'
WHEN I.ISLEMTURU=3 AND I.FATMI=1 THEN  'Alış Fat.'
WHEN I.ISLEMTURU=2 AND I.FATMI=0 THEN  'Satış Fişi'
WHEN I.ISLEMTURU=3 AND I.FATMI=0 THEN  'Alış Fişi'
WHEN I.ISLEMTURU=4 THEN  '(Alacak)Tahsilat '
WHEN I.ISLEMTURU=5 THEN  '(Borç) Ödeme'
END AS ISLEMADI,
CASE
WHEN I.ISLEMTURUALT=0 THEN  ''
WHEN I.ISLEMTURUALT=1 THEN  'Nakit İşlem'
WHEN I.ISLEMTURUALT=2 THEN  'K.K. İşlemi'
WHEN I.ISLEMTURUALT=3 THEN  'Banka İşlemi'
WHEN I.ISLEMTURUALT=4 THEN  'Çek İşlemi'
WHEN I.ISLEMTURUALT=5 THEN  'Senet İşlemi'
END AS ISLEMADIALT,
CASE
WHEN I.BAYIKODU<=0 THEN 'Merkez'
WHEN I.BAYIKODU>0 THEN  B.UNVAN
END AS BADI,
K.USERNAME AS KULADI,
D.KISALTMA AS DOV,
coalesce(CAST(rdb$get_context('USER_TRANSACTION','bky#' ) AS decimal(10,4) ),0) as Bakiy,
CAST(rdb$set_context('USER_TRANSACTION','bky#',coalesce(CAST(rdb$get_context('USER_TRANSACTION','bky#' )AS decimal(10,4) ),0)+ I.BORC - I.ALACAK )AS decimal(10,2) )as Set_Bakiye
FROM CARI_ISLEM I
LEFT JOIN DEPO B ON B.KOD=I.BAYIKODU
LEFT JOIN KULLANICI K ON K.KOD=I.KULKODU
LEFT JOIN DOVIZ D ON D.KOD=I.DOVIZKODU
WHERE I.CARIKODU =:KOD AND I.TARIH>=:T1 AND I.TARIH<=:T2 AND I.DOVIZKODU=:DKODU
ORDER BY I.TARIH, I.KOD
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

merhaba;
esistem kardeş;
gönderdiğim kodu FdQuery den çalıştırıyorum. SP kullanmadan çalışıyor. buradaki sorun parametre gönderememek. yaptığım araştırmalara göre 50000 kaydı 1.22 saniyede hesaplayıp getiriyor. linkine bir bakayım;
viewtopic.php?f=18&t=26792&p=150044&hil ... ye#p150044
bu linkten Yürüyen Bakiye Uygulaması Linkini Tıkla

FDQuery içinden parametre değeri vererek denedim. kayıtları çok hızlı getiriyor. bence faydalı bir kod, müsait olunca denemenizi tavsiye ederim.

sizin kodunuza gelince; kullandığınız kodu paylaştığınız için öncelikle teşekkür ederim.
1 adet CariEkstre Query si,
1 adet BakiyeSifirla Query si
CariEkstre Query sinden önce BakiyeSıfırla Query sini Close Open Yapıyorum.
kullandığım kod;

Kod: Tümünü seç

SELECT CH.ID, CH.CARIID, CH.HRKKOD, CH.MODULID, CH.MODULADI, CH.ISLEMADI, CH.EVRAKNO, CH.TARIH, CH.SAAT,
CH.BORC, CH.ALACAK, CH.DOVIZ, CH.VADESI, CASE CH.VADEDRM  WHEN 'T' Then 'Tamam'  WHEN 'D' Then 'Devam' END AS VADEDRM,
CH.ACIKLAMA, CASE CH.ISLEMTIPI WHEN 'CA' THEN 'Cari Açılış' WHEN 'AD' THEN 'Alacak' WHEN 'BD' THEN 'Borç' WHEN 'KO' THEN 'Ödeme' WHEN 'KT' THEN 'Tahsilat' WHEN 'CG' THEN 'Çek Giriş'WHEN 'CC' THEN 'Çek Çıkış' WHEN 'CI' THEN 'Çek İade'WHEN 'SG' THEN 'Senet Giriş' WHEN 'SC' THEN 'Senet Çıkış' WHEN 'SI' THEN 'Senet İade' WHEN 'GEH' THEN 'Gelen Havale' WHEN 'GIH' THEN 'Giden Havale'  WHEN 'SF' THEN 'Satış Fatura' WHEN 'SIF' THEN 'Satış İade' WHEN 'AF' THEN 'Alış Fatura'WHEN 'AIF' THEN 'Alış İade' WHEN 'HAF' THEN 'Hizmet Alış' WHEN 'HSF' THEN 'Hizmet Satış'  WHEN 'MCB' THEN 'Müşteri Çek Bordro' WHEN 'SCB' THEN 'Şirket Çek Bordro' wHEN 'MSB' THEN 'Müşteri Snt Bordro' WHEN 'SSB' THEN 'Şirket Snt Bordro' WHEN 'PS' THEN 'Per. Satış' WHEN 'PI' THEN 'Per. İade' WHEN 'CVG' THEN 'Giriş Virman' WHEN 'CVC' THEN 'Çıkış Virman' WHEN 'FT' THEN 'Fatura Tahsilat' WHEN 'FO' THEN 'Fatura Ödeme' WHEN 'FHC' THEN ' Fat.Hsp Çıkış' WHEN 'FHG' THEN ' Fat.Hsp Giriş' WHEN 'HFT' THEN 'HizFat. Tahsilat' WHEN 'HFO' THEN 'HizFat. Ödeme' 
WHEN 'HFHC' THEN 'HizFat. HspÇıkış' WHEN 'HFHG' THEN 'HizFat. HspGiriş' WHEN 'VF' THEN 'Vade Farkı' END AS ISLEMTIPI,GCKOD, CH.ILGILINOT,
coalesce(CAST(rdb$get_context('USER_TRANSACTION','bky#' )AS Double Precision ),0) as Bakiye,
CAST(rdb$set_context('USER_TRANSACTION','bky#',coalesce(CAST(rdb$get_context('USER_TRANSACTION','bky#' )AS Double Precision ),0)+ CH.BORC - CH.ALACAK )AS Double Precision ) as Set_Bakiye
FROM TBLCARIHAR as CH
WHERE (CH.CARIID=:CID) and (CH.DOVIZ=:DV) 
order by CH.TARIH asc, CH.ID asc
Gridde bakiyeler Sıfır Geliyor nerede hata yapıyorum.
İsteyen, yapabildiğinden daha fazlasını yapar.
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen esistem »

Selam yazdığın sorguda gördüğüm bir hata görüyorum ondan kaynaklı olabilir, aşağıdaki GCKOD hangi tablodan geliyor ? CH.GCKOD şeklinde yazman gerekiyor sanırım. Normalde sorgunda bir hata yok, Bakiye field ı değeri vermesi lazım.

Kod: Tümünü seç

WHEN 'HFHC' THEN 'HizFat. HspÇıkış' WHEN 'HFHG' THEN 'HizFat. HspGiriş' WHEN 'VF' THEN 'Vade Farkı' END AS ISLEMTIPI,
GCKOD, 
CH.ILGILINOT,
Şimdi tekrar kodunuzu inceledim, CASE seçiminde bazı yerlerde tek tırnak ile WHEN birleşmiş görünüyor, normalde sql i çalıştıramayıp hata vermesi gerekir diye düşünüyorum.

Birde ben bu sistemi kendi programlarımda sürekli kullanırım, Fakat bendeki programlarda Cari hesap görünümleri biraz farklıdır, Cari hesap formunu açtığınızda Üstte bir grid de Cari hesaplar Altında hareketleri görünür, Cari hesaplarda gezdikçe hangi cari hesabın üzerinde iseniz onun hareket kayıtları yürüyen bakiye şeklinde direk görünür. Siz eğer bunu bir raporda göstermek istiyorsanız Stored Procedure ile yapmanız işlemi çok daha hızlandıracaktır diye düşünüyorum. Zaten onu yapmakta çok basit bir sql kodu ile mümkündür. Verdiğiniz linkteki sonuçlar doğrudur tabi fakat şahsen benim yazdığım hiçbir programda şimdiye kadar tek cari hesaba ait 50.000 işlem kaydı olmadı hiç :)
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

CH.GCKOD olarak düzelttim. BAKİYE ile SET_BAKİYE sütunları sıfır olarak geliyor.

Kod: Tümünü seç

  frmDm.QryBakiyeSifirla.close;
  frmDm.QryBakiyeSifirla.open;
  frmDm.QryCariEkstre.Close;
  frmDm.QryCariEkstre.Params[0].AsString:=Trim(EditCariID.Text);
  frmDm.QryCariEkstre.Params[1].AsString:='TL';
  frmDm.QryCariEkstre.Open;
delphi den sorgu bu şekilde çalıştırılıyor. lookup listesinden kayıt seçilerek her kayıt yenilendiğinde yukarıdaki komutlar yeniden çalıştırılıyor.
İsteyen, yapabildiğinden daha fazlasını yapar.
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen esistem »

QryBakiyeSifirla query nizde bir şekilde datasource kısmı QryCariEkstre query niz ile ilişkilendirilmiş olabilirmi ? yada başka bir query ile ilişkili olabilirmi? veya seçtiğiniz cari hesabın hareketleri olmayabilirmi ? yada QryBakiyeSifirla query nizde yazan kod hatalı olabilir.
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

bütün soruları kontrol ettim. QryBakiyeSifirla için datasource Tanımlamamıştım bir adet tanımladım ve QryBakiyeSıfırlaya Bağladım. seçtiğim carinin hareketleri görüntüleniyor. cari kayıt çok her seçilen cari için onlarca kayıt var.
QrybakiyeSifirla için yazdığın kod

Kod: Tümünü seç

SELECT rdb$set_context( 'USER_TRANSACTION' ,'bky#' ,0) from rdb$database;
Qrycariekstre ile QryBakiyeSifirla arasında ek bir ayarlama yapmak gerekmiyormu.

carinin hareketleri listelendiği zaman BAKIYE sütunundaki kayıtların hepsinde sıfır değeri çıkıyor. SET_BAKIYE sütünunda ilk kayıtta 1 değeri görüntüleniyor. sonraki kayıtlarda sıfır değeri çıkıyor.
İsteyen, yapabildiğinden daha fazlasını yapar.
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

Firebird in 2.5.2 versiyonunu kullanıyorum ondan olabilir mi acaba
İsteyen, yapabildiğinden daha fazlasını yapar.
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen boreas »

Öncelikle @esistem'e paylaşırken blog adresimide kaynak gösterme nezaketi gösterdiği için çok teşekkür ederim.
Burada yaşadığınız sorun şu olabilir eğer borç ya da alacak fieldlarından biri null ise işlem sonucu yanlış çıkar. Bu yüzden CH.BORC - CH.ALACAK kısmına coalesce(CH.BORC,0) - coalesce(CH.ALACAK,0) diyerek denemenizi tavsiye ederim.
....
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

sonuçlandıramasaydım uyuyamazdım herhalde
sorun aynen dediğiniz gibiymiş. bir daha bu ayrıntıyı unutmam inşallah
:bravo: :bravo: :bravo: :bravo: :bravo: :bravo: :bravo: :bravo: :bravo: :bravo:

ayrıca @boreas kardeş hazırlayıp paylaşma inceliğinde bulunduğunuz kod için ve gün boyu ilgi ve alakasını eksik etmeyen @esistem forma ve değerli üyelerine çok teşekkür ederim.
İsteyen, yapabildiğinden daha fazlasını yapar.
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen boreas »

Sorunun çözülmesine sevindim. :)
....
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen esistem »

Selam,
Siteye ancak girebildim kusura bakmayın.
@boreas merhaba, şahsen sizin ve tuğrul beyin bloglarına boş vaktim oldukça giriyorum, değerli paylaşımlarınız için asıl ben teşekkür ederim.
@akuyumcu63 arkadaşın sorununa gelince, benim hiç aklıma gelmezdi borç yada alacak alanlarından biri null olsun zira tabloları oluştururken alan tipi ne olursa olsun mutlaka varsayılan bir değer veririm, olmadık yerde olmadık bi hata veriyor sonra böyle uğraşıp duruyorum :)
akuyumcu63
Üye
Mesajlar: 386
Kayıt: 02 Tem 2007 09:43

Re: firebird de Yürüyen Bakiye ve CURSOR

Mesaj gönderen akuyumcu63 »

cari kaydın harketleri içinden arama yaparken yada iki tarih arası filitreleme yaparken bakiye yeniden hesaplanıyor. o zaman bakiye yanlış oluyor.
cari kaydın heraketlerinin tümünü çağırdıktan sonra yapılan filitrelemelerde bakiyeninin yeniden hesaplanmasını nasıl engelleyebiliriz.
İsteyen, yapabildiğinden daha fazlasını yapar.
Cevapla