Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
FB Sp içinde Select
#11
Benim demek istediğim aşağıdaki gibi bir şeydi. Deneyip sonucunu bildirir misiniz?

create or alter procedure sp_test(tar1 date, tar2 date)
returns(.....)
as
begin
     for
         select ..... from tablo1 where tarih between :tar1 and :tar2
         union all
         select ..... from tablo2 where tarih between :tar1 and :tar2
      into ...... do
      suspend;
end
Cevapla
#12
(21-01-2019, Saat: 20:12)mcuyan Adlı Kullanıcıdan Alıntı:
(21-01-2019, Saat: 19:40)anemos Adlı Kullanıcıdan Alıntı: Çünkü view, parametre kabul etmez. Tüm kayıtlar döndükten sonra kriter verebiliyoruz. Ancak SP içinde önce filitreleyip sonra birleştirmek mümkün. SP' nizi bilmiyoruz ama, hatalı kullandığınızı tahmin ediyorum.

Biraz uzun ama ...

create or alter procedure KASA (
    TAR1 date,
   TAR2 date)
returns (
   SATTARIHI date,
   SATTIPI varchar(10),
   SATKUL varchar(10),
   TOP float)
as
begin
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID <> 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 -- union all
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID = 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     -- union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select GTAR as SATTARIHI, 'GİDER' as SATTIPI, GCIKKASA as SATKUL, round(sum(GTUTAR), 2) as TOP
     from GIDER
     where (GTAR between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     --union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select SFATTAR as SATTARIHI, 'İSKONTO' as SATTIPI, SATKUL as SATKUL,
            round(sum(SFATTOPLAM - SFATANATUTAR), 2) as TOP
     from SFATDETAY
     left join SBASLIK on SFATDETAY.SFATBASID = SBASLIK.SATFATNO
     where SFATTOPLAM <> SFATANATUTAR and
           SFATTOPLAM > 0 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SFATTAR, SATTIPI, SATKUL
     order by 1, 3
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
end

Birinci ve ikinci for dongusunde satfirmaid <>2 and esittir 2 yapmissiniz sorgu mantiginizda bir sorun yokmu?
Her durumda tum satfirmaid leri getirecek. Yani tek for dongusu yapip satfirmaid kosulunu kaldirinca ayni isi yapacaktir
Cevapla
#13
Burada döngüye neden ihtiyacınız var ? Normal bir select ile (FOR/DO olmadan) istediğiniz değerleri istediğiniz değişkenlerin içine atmaya müsaade etmiyor mu ? Döngü kullanımı bana CURSOR kullanımını anımsattı. CURSOR'lar da genel anlamda yavaştırlar. FireBird'den hiç anlamam ama yine de mantıklı görünmedi bana, çünkü sorgunuzda GROUP BY kullanmışsınız. O halde tek değerler gelecektir zaten. Siz de gelen değerleri değişkenlerinize atayabilirsiniz. Döngü lüzumsuz gibi göründü gözüme. Ama belki de bu garip syntax'a ihtiyaç vardır, bilemiyorum tabii.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#14
KASA için bir view yazılıp, ordan gruplayarak çekmek sanki daha basit ve kullanışlı olur gibi geldi banada.
WWW
Cevapla
#15
(21-01-2019, Saat: 20:12)mcuyan Adlı Kullanıcıdan Alıntı:
(21-01-2019, Saat: 19:40)anemos Adlı Kullanıcıdan Alıntı: Çünkü view, parametre kabul etmez. Tüm kayıtlar döndükten sonra kriter verebiliyoruz. Ancak SP içinde önce filitreleyip sonra birleştirmek mümkün. SP' nizi bilmiyoruz ama, hatalı kullandığınızı tahmin ediyorum.

Biraz uzun ama ...

create or alter procedure KASA (
    TAR1 date,
   TAR2 date)
returns (
   SATTARIHI date,
   SATTIPI varchar(10),
   SATKUL varchar(10),
   TOP float)
as
begin
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID <> 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 -- union all
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID = 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     -- union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select GTAR as SATTARIHI, 'GİDER' as SATTIPI, GCIKKASA as SATKUL, round(sum(GTUTAR), 2) as TOP
     from GIDER
     where (GTAR between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     --union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select SFATTAR as SATTARIHI, 'İSKONTO' as SATTIPI, SATKUL as SATKUL,
            round(sum(SFATTOPLAM - SFATANATUTAR), 2) as TOP
     from SFATDETAY
     left join SBASLIK on SFATDETAY.SFATBASID = SBASLIK.SATFATNO
     where SFATTOPLAM <> SFATANATUTAR and
           SFATTOPLAM > 0 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SFATTAR, SATTIPI, SATKUL
     order by 1, 3
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
end

Ayrıca gözüme çarpan bir kaç garip durumu daha belirteyim. Belki ben Firebird bilmediğim için bana garip geliyor olabilir. Üçüncü SELECT cümlenizde, SatTarihi, SatTipi, SatKul isimli fiziksel alanlara göre gruplama yapmışsınız ama tablodan başka alanları seçiyorsunuz. Normalde gruplama dışındaki alanların seçilebilmesi için o alanlara aggregation yapmak lazımdır.(AVG, SUM, MAX, MIN vb.)

 Bir diğer husus ise, bu SELECT cümleleriniz birbiri ile birleştirilmediği için (UNION); her bir cümle sizin değişkenlerinizin üzerine yazmaz mı ? Yani her halükarda her zaman son SELECT cümlesinden dönecek olan değerleri görmezmiyiz değişkenlerinizin içinde ?
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#16
2. sorunuz için cevap vereyim hocam,
her suspend'dan önceki for select dongusu, çıktı olarak verilen değişkenlere ayrı satırlar halinde yazılıp ardışık tek bir tablo oluşturma şeklinde çalışır.

Fakat yine söylüyorum ben olsam view ile yapardım bu işlemi.
Aşağıdaki gibi bir view yazıp, SP içinden gruplayarak çekmek daha mantıklı geldi bana,

CREATE VIEW VIEW_KASA(
   TARIH,
   TIPI,
   KULLANICI,
   TOPLAM)
AS
select TARIH, TIPI, KULLANICI, TOPLAM from
(
select SATTARIHI AS TARIH, SATTIPI AS TIPI, SATKUL AS KULLANICI, SATGENELTOP AS TOPLAM
    from SBASLIK
    where SATFIRMAID <> 2

UNION ALL

select SATTARIHI AS TARIH, SATTIPI AS TIPI, SATKUL AS KULLANICI, SATGENELTOP AS TOPLAM
    from SBASLIK
    where SATFIRMAID = 2

UNION ALL

select GTAR as TARIH, IIF (ID>0,'GİDER','') AS TIPI, GCIKKASA AS KULLANICI, GTUTAR AS TOPLAM
    from GIDER

UNION ALL

select SFATTAR as TARIH, IIF (ID>0,'İSKONTO','') AS TIPI, SATKUL AS KULLANICI, (SFATTOPLAM - SFATANATUTAR) as TOPLAM
    from SFATDETAY
    where SFATTOPLAM <> SFATANATUTAR and
          SFATTOPLAM > 0 
)
WWW
Cevapla
#17
(21-01-2019, Saat: 22:10)anemos Adlı Kullanıcıdan Alıntı: Benim demek istediğim aşağıdaki gibi bir şeydi. Deneyip sonucunu bildirir misiniz?

create or alter procedure sp_test(tar1 date, tar2 date)
returns(.....)
as
begin
    for
        select ..... from tablo1 where tarih between :tar1 and :tar2
        union all
        select ..... from tablo2 where tarih between :tar1 and :tar2
     into ...... do
     suspend;
end

SP içinde For içinde yazdım.. Fakat view'e göre çok performans kaybı yaşadım Hocam..

(22-01-2019, Saat: 09:11)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı:
(21-01-2019, Saat: 20:12)mcuyan Adlı Kullanıcıdan Alıntı: Biraz uzun ama ...

create or alter procedure KASA (
    TAR1 date,
   TAR2 date)
returns (
   SATTARIHI date,
   SATTIPI varchar(10),
   SATKUL varchar(10),
   TOP float)
as
begin
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID <> 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 -- union all
 for select SATTARIHI, SATTIPI, SATKUL, round(sum(SATGENELTOP), 2) as TOP
     from SBASLIK
     where SATFIRMAID = 2 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     -- union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select GTAR as SATTARIHI, 'GİDER' as SATTIPI, GCIKKASA as SATKUL, round(sum(GTUTAR), 2) as TOP
     from GIDER
     where (GTAR between :TAR1 and :TAR2)
     group by SATTARIHI, SATTIPI, SATKUL
     --union all
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
 for select SFATTAR as SATTARIHI, 'İSKONTO' as SATTIPI, SATKUL as SATKUL,
            round(sum(SFATTOPLAM - SFATANATUTAR), 2) as TOP
     from SFATDETAY
     left join SBASLIK on SFATDETAY.SFATBASID = SBASLIK.SATFATNO
     where SFATTOPLAM <> SFATANATUTAR and
           SFATTOPLAM > 0 and
           (SATTARIHI between :TAR1 and :TAR2)
     group by SFATTAR, SATTIPI, SATKUL
     order by 1, 3
     into :SATTARIHI, :SATTIPI, :SATKUL, :TOP
 do
   suspend;
end

Ayrıca gözüme çarpan bir kaç garip durumu daha belirteyim. Belki ben Firebird bilmediğim için bana garip geliyor olabilir. Üçüncü SELECT cümlenizde, SatTarihi, SatTipi, SatKul isimli fiziksel alanlara göre gruplama yapmışsınız ama tablodan başka alanları seçiyorsunuz. Normalde gruplama dışındaki alanların seçilebilmesi için o alanlara aggregation yapmak lazımdır.(AVG, SUM, MAX, MIN vb.)

 Bir diğer husus ise, bu SELECT cümleleriniz birbiri ile birleştirilmediği için (UNION); her bir cümle sizin değişkenlerinizin üzerine yazmaz mı ? Yani her halükarda her zaman son SELECT cümlesinden dönecek olan değerleri görmezmiyiz değişkenlerinizin içinde ?

Hoam 3. Select'de de Sum(GTar) olduğunu gözden kaçırdınız sanırım.

Her bir select'in sonucu Tarihsel olarak kasiyer, Gün ve tutar olarak sum yapılması istenilen. Yani aynı tarite KASA1'in yaptığı pos,nakit ve diğer işlemlerin toplanılıp gösterilmesini istediğim için öyle yaptım. Yani dediğiniz gibi üst üste bindirmesi laızm. Ama her Select'in sonucu Sattipi olarak farklı data getirdiği için üst üste bindirme olmuyor.

(22-01-2019, Saat: 09:23)esistem Adlı Kullanıcıdan Alıntı: 2. sorunuz için cevap vereyim hocam,
her suspend'dan önceki for select dongusu, çıktı olarak verilen değişkenlere ayrı satırlar halinde yazılıp ardışık tek bir tablo oluşturma şeklinde çalışır.

Fakat yine söylüyorum ben olsam view ile yapardım bu işlemi.
Aşağıdaki gibi bir view yazıp, SP içinden gruplayarak çekmek daha mantıklı geldi bana,

CREATE VIEW VIEW_KASA(
   TARIH,
   TIPI,
   KULLANICI,
   TOPLAM)
AS
select TARIH, TIPI, KULLANICI, TOPLAM from
(
select SATTARIHI AS TARIH, SATTIPI AS TIPI, SATKUL AS KULLANICI, SATGENELTOP AS TOPLAM
    from SBASLIK
    where SATFIRMAID <> 2

UNION ALL

select SATTARIHI AS TARIH, SATTIPI AS TIPI, SATKUL AS KULLANICI, SATGENELTOP AS TOPLAM
    from SBASLIK
    where SATFIRMAID = 2

UNION ALL

select GTAR as TARIH, IIF (ID>0,'GİDER','') AS TIPI, GCIKKASA AS KULLANICI, GTUTAR AS TOPLAM
    from GIDER

UNION ALL

select SFATTAR as TARIH, IIF (ID>0,'İSKONTO','') AS TIPI, SATKUL AS KULLANICI, (SFATTOPLAM - SFATANATUTAR) as TOPLAM
    from SFATDETAY
    where SFATTOPLAM <> SFATANATUTAR and
          SFATTOPLAM > 0 
)

VArolan şu anki yazdığınız View'ın aynısı hocam. Fakat olay 5 yıllık data olunca.. Her gün için komple select'in alınıp sonrasında tarih ile kriter vermek uzun zaman alıyor.. Fakat Ne kadar uzun olursa olsun, For+INTO'lu bir SP den daha kısa sürede data getiriyor ilginç bir şekilde..

Bu arada cevaplar ve zaman ayırdığınız için çok teşekkür ediyorum.


Ek Dosyalar Resimler
   
// Bilgi paylaştıkça çoğalır.. 

Cevapla
#18
Hocam View sonuçta kayıtları yaparken tabloya işliyor, SP ise View içindeki 4 select i her defasında farklı tablolardan alıp işleyip birleştiriyor, mecburen biraz geç kalacaktır. SP içerisinde bilgileri View den alıp çıktıları veren sorguyu yazarsanız orta yolu bulursunuz bence Smile
WWW
Cevapla
#19
(22-01-2019, Saat: 15:38)esistem Adlı Kullanıcıdan Alıntı: Hocam View sonuçta kayıtları yaparken tabloya işliyor, SP ise View içindeki 4 select i her defasında farklı tablolardan alıp işleyip birleştiriyor, mecburen biraz geç kalacaktır. SP içerisinde bilgileri View den alıp çıktıları veren sorguyu yazarsanız orta yolu bulursunuz bence Smile
Merhaba @esistem  view lerde tabloya isleme olayi yoktur. bir view de veride olmaz. sadece veri tanımı tutuluyor. Her cagrildiginda ilgili tablo veya tablolardan view yapisina uygun sekilde veriler cekilip gosterilir diye biliyorum ben.
Cevapla
#20
Bendr @klavye hocamin dedigi gibi biliyorum.. view'lere çok sık kullanılan bir select bloğu diyebiliyoeuz diye biliyorum..

Bu arada sp deki tarih filtresi haricinde sql kodlarinin aynisi hocam hic bir fark yok.. hatta indexleri de selectin icindekicgroup lara gore duzenledim. Fakat celeron cpu lu pc lerde cidden 5 6 sn gibi uzun surede data getiriyor..
// Bilgi paylaştıkça çoğalır.. 

Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Select iif As İfadesinde Oluşan Boşluklar sunbeki 8 2.171 21-04-2022, Saat: 22:55
Son Yorum: sunbeki
  SQLQueryl : Cannot open a non-select statement hatası sadikacar60 9 2.899 04-04-2021, Saat: 20:24
Son Yorum: sadikacar60
  SELECT a FROM (1, 2, 3) nkyek 4 2.842 03-06-2020, Saat: 21:40
Son Yorum: nkyek
  Firebird ile aynı server içindeki iki ayrı database deki tablolar arasında select serkansirin001@gmail.com 6 4.725 03-09-2019, Saat: 01:05
Son Yorum: mcuyan
  Select bolumunde parametre kullanmak klavye 15 10.140 16-03-2017, Saat: 15:58
Son Yorum: esistem



Konuyu Okuyanlar: 1 Ziyaretçi