Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Firebird CariBakiye Hesaplama Stored Procedure
#1
Merhaba Bir müşterimin istediği üzerine yazmaya başladığım küçük çaplı ön muhasebe programında kullandığım CariBakiyeHesaplama stored procedure ü paylaşıyorum.

stored procedure ler object pascal da kullandığımız procedurlere benzer fonksiyon gibi geriye değer de döndürebilirler

Cariler Tablomda
borc,alacak,bakiye,yerelborc,yerelalacak,yerelbakiye alanlarım var bu alanlar numeric 15,4 olarak tanımlı,
firma_id (integer) alanı programda birden fazla firma tanımlayıp kullanılabiliyor firma ayracı diyebiliriz foreign key ile firmalar tablosunda ki firma_id alanına bağlı
cari_id (integer) primary key olarak tanımlı.

carihareket tablosunda da aynı cari_id, ve firma_id alanları var

carihareket tablosuna yeni bir kayıt eklendiğinde, silindiğinde, değiştirildiğinde ilgili kaydın bağlı bulunduğu cariler tablosundada borc,alacak,bakiye.. alanlarımın güncellenmesini istiyorum bunuda SP_CBAKIYE_HESAPLA ismini verdiğim stored procedure ile yapacağız.

sp de iki input parametresi tanımlıyorum gfirma_id (sp parametre olarak gelecek firma id si ) integer tanımlı. gcari_id (sp_parametre olarak cari id si) integer

ibexpert kullanıyorsanız input parameters bölümünde tanımlayabilirsiniz input parametreleriniz

Procedure de tanımladığım değişkenler yine ibexpert de variables kısmında tanımlayabiliyorsunuz
DMN_PARATUTAR benim numeric 15,4 olarak tanımladığım domain siz numeric 15,4 olarak yada double kullanıyorsanız double seçebilirsiniz



TBORC DMN_PARATUTAR = 0;
TALACAK DMN_PARATUTAR = 0;
TBAKIYE DMN_PARATUTAR = 0;
TYEREL_BORC DMN_PARATUTAR = 0;
TYEREL_ALACAK DMN_PARATUTAR = 0;
TYEREL_BAKIYE DMN_PARATUTAR = 0;
KAYIT_SAYISI integer; // gcari_id parametresi ile cariharekete bulunan kayıt sayısı



SELECT COUNT(*) FROM carihareket 
WHERE carihareket.cari_id = :gcari_id
INTO :kayit_sayisi; // kayit_sayisi değişkenine tablodaki kayıt sayısını aktardık

if (kayit_sayisi>0) then // kayıt var ise
begin
           
           select
           sum (carihareket.borc), 
           sum (carihareket.alacak),
           sum (carihareket.yerelborc),
           sum (carihareket.yerelalacak)
           from carihareket
           where 1=1
           and carihareket.firma_id=:gfirma_id
           and carihareket.cari_id=:gcari_id
           

           
into // select sıramızla aynı olacak şekilde dönen değerleri değişkenlerimize aktarıyoruz
:tborc,
:talacak,
:tyerel_borc,
:tyerel_alacak;
           
           if (tborc is null) then tborc=0; // her ihtimale karşı null ise 0 atıyoruz
           if (talacak is null) then talacak=0;
           if (tyerel_borc is null) then tyerel_borc=0;
           if (tyerel_alacak is null) then tyerel_alacak=0;
           
           
tbakiye=tborc-talacak; // toplam borçtan toplam alacağı çıkarıp tbakiye değişkenine aktarıyoruz
tyerel_bakiye=tyerel_borc-tyerel_alacak;
if (tbakiye is null) then  tbakiye=0;
if (tyerel_bakiye is null) then  tyerel_bakiye=0;
           
// değişkenlerimize atadığımız değerleri cariler tablosunda ki ilgili alanlarımıza update ediyoruz
                           update cariler set
                           cariler.borc=:tborc,
                           cariler.alacak=:talacak,
                           cariler.bakiye=:tbakiye,
                           cariler.yerelborc=:tyerel_borc,
                           cariler.yerelalacak=:tyerel_alacak,
                           cariler.yerelbakiye=:tyerel_bakiye
                           where 1=1
                           and cariler.firma_id=:gfirma_id
                           and cariler.cari_id=:gcari_id;
                           
end

           if (kayit_sayisi=0) then // hiç kayıt yok ise örnek carihareketi son kaydı sildik alanlarımıza 0 değeri atıyoruz
           begin
           
                       update cariler set
                       cariler.borc=0,
                       cariler.alacak=0,
                       cariler.bakiye=0,
                       cariler.yerelborc=0,
                       cariler.yerelalacak=0,
                       cariler.yerelbakiye=0
                       where 1=1
                       and cariler.firma_id=:gfirma_id
                       and cariler.cari_id=:gcari_id;
           
           
           end



Procedürümüzü delphi tarafında query nesnesi ile de parametreleri vererek çalıştırabiliriz
EXECUTE PROCEDURE SP_CBAKIYE_HESAPLA(1, 1)
trigerla

After insert trigerına
 execute procedure sp_cbakiye_hesapla(new.firma_id,new.cari_id);
After delete trigerına
 execute procedure sp_cbakiye_hesapla(old.firma_id,old.cari_id);
after update trigerına
 execute procedure sp_cbakiye_hesapla(old.firma_id,old.cari_id);
aslında update trigerında kontrolü yapmamız daha mantıklı borc,alacak v.s alanlar değişmediğinde örnek sadece açıklama alanı değişti yine çalışaktır gereksiz yük

cariler tablonuzda hiç borç,alacak v.s kullanmayada bilirsiniz benim yapı denormalize bir yapı buradaki kodlarda bu yapıya göre.
son olarak ddl kodları



SET TERM ^ ;

create or alter procedure SP_CBAKIYE_HESAPLA (
   GFIRMA_ID integer not null,
   GCARI_ID integer not null)
as
declare variable TBORC DMN_PARATUTAR = 0;
declare variable TALACAK DMN_PARATUTAR = 0;
declare variable TBAKIYE DMN_PARATUTAR = 0;
declare variable TYEREL_BORC DMN_PARATUTAR = 0;
declare variable TYEREL_ALACAK DMN_PARATUTAR = 0;
declare variable TYEREL_BAKIYE DMN_PARATUTAR = 0;
declare variable KAYIT_SAYISI integer;
begin

SELECT COUNT(*) FROM carihareket WHERE carihareket.cari_id = :gcari_id INTO :kayit_sayisi;

if (kayit_sayisi>0) then
begin
           
           select
           sum (carihareket.borc),
           sum (carihareket.alacak),
           sum (carihareket.yerelborc),
           sum (carihareket.yerelalacak)
           from carihareket
           where 1=1
           and carihareket.firma_id=:gfirma_id
           and carihareket.cari_id=:gcari_id
           

           
into
:tborc,
:talacak,
:tyerel_borc,
:tyerel_alacak;
           
           if (tborc is null) then tborc=0;
           if (talacak is null) then talacak=0;
           if (tyerel_borc is null) then tyerel_borc=0;
           if (tyerel_alacak is null) then tyerel_alacak=0;
           
           
tbakiye=tborc-talacak;
tyerel_bakiye=tyerel_borc-tyerel_alacak;
if (tbakiye is null) then  tbakiye=0;
if (tyerel_bakiye is null) then  tyerel_bakiye=0;
           
                           update cariler set
                           cariler.borc=:tborc,
                           cariler.alacak=:talacak,
                           cariler.bakiye=:tbakiye,
                           cariler.yerelborc=:tyerel_borc,
                           cariler.yerelalacak=:tyerel_alacak,
                           cariler.yerelbakiye=:tyerel_bakiye
                           where 1=1
                           and cariler.firma_id=:gfirma_id
                           and cariler.cari_id=:gcari_id;
                           
end

           if (kayit_sayisi=0) then
           begin
           
                       update cariler set
                       cariler.borc=0,
                       cariler.alacak=0,
                       cariler.bakiye=0,
                       cariler.yerelborc=0,
                       cariler.yerelalacak=0,
                       cariler.yerelbakiye=0
                       where 1=1
                       and cariler.firma_id=:gfirma_id
                       and cariler.cari_id=:gcari_id;
           
           
           end
END
^

SET TERM ; ^

/* Following GRANT statements are generated automatically */

GRANT SELECT ON CARIHAREKET TO PROCEDURE SP_CBAKIYE_HESAPLA;
GRANT SELECT,UPDATE ON CARILER TO PROCEDURE SP_CBAKIYE_HESAPLA;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE SP_CBAKIYE_HESAPLA TO SYSDBA;

“Do. Or do not. There is no try.”
Cevapla
#2
Paylaşım için teşekkürler.
Emeğinize sağlık.
There's no place like 127.0.0.1
WWW
Cevapla
#3
Merhaba,
Değerli katkılarınızdan dolayı teşekkür ederim.
Cevapla
#4
Merhaba,
Değerli katkınız için teşekkürler. 

Programı yeni yazmaya başlamışsınız o yüzden naçizane bir önerim olacak. 
Bu yapıyı EticariPlus u ilk yazdığımda kullanmıştım fakat oldukça hantal kalıyor. Zira Cari_Hareket tablosunda her insert, update veya delete işleminde trigger tetikleyip, seçili cari hesap için bütün hareketlerde her defasında SUM alıp Cari tablosunda Borc, Alacak alanlarını güncelliyorsunuz. Bunun yerine şöyle basit bir olay kullanabilirsiniz. 
Cari tablosuna yeni kayıt açıldığında, Borc ve Alacak varsayılan 0 (Sıfır) girilir. 
Cari_Hareket tablosunda da Borc ve Alacak alanları zaten var, 
Daha sonra,

Cari_Hareket_AI (After Insert)
UPDATE Cari SET Borc = Borc + New.Borc, Alacak = Alacak + New.Alacak WHERE id = New.Cari_id;

Cari_Hareket_AU (After Update)
UPDATE Cari SET Borc = Borc - Old.Borc, Alacak = Alacak - Old.Alacak WHERE id = Old.Cari_id;
UPDATE Cari SET Borc = Borc + New.Borc, Alacak = Alacak + New.Alacak WHERE id = New.Cari_id;

Cari_Hareket_AD (After Delete)
UPDATE Cari SET Borc = Borc - Old.Borc, Alacak = Alacak - Old.Alacak WHERE id = Old.Cari_id;

şeklinde çok çok daha hızlı çalışması sağlanabilir.
WWW
Cevapla
#5
@esistem hocam bir defasında aynen sizin yaptığınız şekilde yaptım 2-3 yıl oluyor herhalde , yanlış hesaplama yapıyormu diye testler yapmıştım bir yerde yanlış hesaplamıştı o case i hatırlamıyorum (çok kurcalamıştım) belkide ozamanki kodlarım tam sizin ki gibi değildir yine bunu da örnek bir yerde kullanıp test ederim.

“Do. Or do not. There is no try.”
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  pardusda dbeaver ıle fırebırd kullanımı hakkında sadikacar60 8 483 29-02-2024, Saat: 17:50
Son Yorum: Hayati
  store procedure problemi sadikacar60 10 835 26-02-2024, Saat: 14:37
Son Yorum: sadikacar60
  Firebird Sound_ex Kodu. COMMANDX 1 276 28-01-2024, Saat: 01:56
Son Yorum: maydin60
  Firebird ile FIFO Hesaplama Nasıl yapılır? klavye 0 334 17-08-2023, Saat: 12:33
Son Yorum: klavye
  IBExpert ile Firebird Veri Kurtarma DelphiCanR 6 7.424 19-07-2023, Saat: 14:42
Son Yorum: baloglurecep



Konuyu Okuyanlar: 1 Ziyaretçi