AdoQuery Tarihler Arası Sorgu

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

AdoQuery Tarihler Arası Sorgu

Mesaj gönderen bobasturk »

Merhabalar, Hayırlı bayramlar;

Forumda sorunum hakkında arama yaptım ve çıkan yedi sayfalık sonucu inceledim, ustalarımın verdiği öreliri uyguladım ama nafile sonucu çözemedim ve anlam veremedim.

Access veri tabanı kullanıyorum ve delphi7 ile çalışıyorum. iki tarih arası sorgulama yapmam gerekiyor. Normal bildiğim yoldan parametreli sorguyu yaptım aşağıdaki gibi,

Kod: Tümünü seç

procedure TFrmSevkIstatistik.suiButton1Click(Sender: TObject);
var
  tarih1, tarih2:tdatetime;
  begin
    dm1.SevkToplamADOQry.Close;
    dm1.SevkToplamADOQry.SQL.Clear;
    dm1.SevkToplamADOQry.SQL.Add('select*from PRS_SEVK');
    dm1.SevkToplamADOQry.SQL.Add('where KAYIT_TARIHI between :tarih1 and :tarih2');
    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih1').Value:=cxdateedit1.Date;
    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih2').Value:=cxdateedit2.Date;
    dm1.SevkToplamADOQry.Open;
    dm1.SevkToplamADOQry.Last;

    dbtext1.Caption:=inttostr(dm1.SevkToplamADOQry.fieldbyname('toplam').AsInteger);
end;
fakat sorgu çalışmadı parameters 'tarih1' not found hatası ile karşılaştım tarih1 adlı parametreyi bulamıyor. arama sonucunda çıkan konularda bu şekil kullanma öneriliyor. benim sorgu niçin parametreyi bulamıyor anlayamadım. Bu sorgu cümlesinde hatam nedir acaba.

Kolay gelsin tekrar hayırlı bayramlar
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

- Komik gelecek ama sorunun parametre ile ilgisi olmayabilir. Ne zaman parametre hatası alsam sonucunda artık ilk baktığım şey Connection tanımını yapıp yapmadığımdır. :lol:

dm1.SevkToplamADOQry'e ait Connection tanımlaması unutulmadı değil mi ?

- Bir de parametreye Date aktarmak istiyorsan şöyle yapmalısın. Bundan da hata alabilirsin.

// Uses'a eğer yoksa DB eklemen gerekir.

Kod: Tümünü seç

    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih1').DataType := ftDate;
    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih1').Value:=cxdateedit1.Date;
    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih2').DataType := ftDate;
    dm1.SevkToplamADOQry.Parameters.ParamByName('tarih2').Value:=cxdateedit2.Date;
Resim
Resim ....Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhabalar,

:oops: :oops: :oops: Ne diyeceğimi bilemiyorum, ustam tahmininiz doğru connection ları belirtmemişim. Bu güzel Bayram günü sizleri rahatasız ettim. :oops: :oops: :oops:

@mrmarman ustam bu ikinci sefer oldu sizin bize verdiğiniz cevaplarda bu alanların datatype lerini illaki belirtiyorsunuz. Alan zaten vt de tarih/saat olarak ayarlı bu type yi belirtmenin şartı veya faydası nedir acaba? öğrenmek adına açıklarsanız ezbere gitmemiş oluruz.

Kolay gelsin.
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Selam...
@mrmarman yazdı:- Komik gelecek ama sorunun parametre ile ilgisi olmayabilir. Ne zaman parametre hatası alsam sonucunda artık ilk baktığım şey Connection tanımını yapıp yapmadığımdır.
- Neden komik geldiğini anladın umarım. Parametre ile Connection'un -direkt- ne alakası var ? İşte bu komik.
@bobasturk yazdı:Alan zaten vt de tarih/saat olarak ayarlı bu type yi belirtmenin şartı veya faydası nedir acaba? öğrenmek adına açıklarsanız ezbere gitmemiş oluruz.
- Aslında ezbere bir durum var ortada. Benim söylediğim de %100 doğru demiyorum. Kuşkulu durum şu, DataType versek de vermesek de genellikle çalışıyor. Her zaman değil ama bazen hata alınıyor.

- Parametre ile Connection'un -direkt- ne alakası var ? dedik aynı şekilde Tip Uyuşmazlığı hatasında da hatanın kaynağı bulunması imkansız gibi bazı durumlar söz konusu var. Bu nedenle datatype olayının üzerine ısrarla basma ihtiyacı duydum. SQL ile aramda kişisel problemim var diyelim istersen buna... :lol: :lol: :lol:

- Etik olarak bakarsam her zaman istenen tip hangisi ise o tipe dönüşüm önceden yapılmalı diyorum. Aslında yaptığımız da bundan ibaret.

- Kendiliğinde otomatik yapılsa bile bunun otomatize edilemediği durumlar olabilir, mesajımın sonudaki örnekte buna değinicem.

- Aşağıdaki vereceğim iki örnek de çalışacaktır. Anlamak adına faydalı olacak. Parametreye birinde String tipinde değer atıycam diğerinde Date tipinde.

Kod: Tümünü seç

    SQL.Text := 'SELECT * FROM Tablo WHERE Tarih = :d1';
    Parameters.ParamByName('d1').Value := '10.09.2006';
    Active := True;

Kod: Tümünü seç

    SQL.Text := 'SELECT * FROM Tablo WHERE Tarih = :d1';
    Parameters.ParamByName('d1').Value := StrTodate('10.09.2006');
    Active := True;
- Veritabanı derleyicisi alanın Date tipinde olduğunu biliyor ve bizden parametrenin de karşılaştırma adına date tipinde gelmesini bekliyor.

- Şimdi bunu irdeleyelim. Nasıl oluyor da parametre atamasını hem Text olarak verince çalışıyor hem de Date verince ? Parametre Value değeri Variant da ondan.

- Ama bu beni tatmin etmiyor çünkü Variant tipi bukalemun gibi her kılığa giren bir tiptir.

- HATA yoksa neden buna gerek duyudun ? ve hata nerede ortaya çıkacak o zaman ? sorularını duyar gibiyim... Kullanıcı girişlerinde, system tarafından belirlenmiş tarih formatı dışında bir girişle karşılaşıldığında olabilir veya tahmin edemediğim başka yerlerde.

- Bu satırları yinelememdeki amacımı kısaca özetlersem, her zaman hata almazsınız. Ama bir gün bir yerde SQL çalışırken atadığınız parametrede tip uyuşmazlığı hatası alırsanız bu yazdıklarımı hatırlayınız ve DataType tanımınını ekleyiniz. Hatanız bertaraf edilmiş olacaktır. :idea:
En son mrmarman tarafından 24 Eki 2006 12:36 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Resim
Resim ....Resim
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhaba,

@mrmarman ustam kıymetli zamanınızı ayırıp eğitici açıklamalarınızdan ve tecrübelerinizin paylaşımından dolayı teşekkür ederim.

Kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Mesaj gönderen Opt2000 »

Selam,

Herhangi bir test yapmadım, ama aklıma gelen bir iki nokta var.

Date tipi aslında bilgisayarda float bir sayı olarak tutulur. Tam sayı kısmı tarih olarak, noktalı kısım ise saat olarak değerlendirilir.

Eğer Parametre olarak Date tipini özellikle belirmezseniz, Value değeri variant olduğu için gelen veriye göre bir tahminde bulunacak. Eğer gönderdiğiniz veri salt tarih ise (yani içinde saat yoksa) o zaman verinin integer olduğunu düşünecek ve veri uyumsuzluğundan dolayı sorun çıkaracak. Bilgisayarın integeri double (float) olarak yorumlayabileceğini düşünebilirsiniz, ama bu her zaman geçerli olmayabilir. Ki burada C kütüphanelerine gönderme olduğu için geçerli olmama olasılığı da yüksektir. (Açıklamasını en sona yazdım).

Eğer verdiğiniz tarih aynı zamanda saati de içeriyorsa, o zaman veri tiplerinin pascal tarafından nasıl değerlendirildiği ile ilgili bir sıkıntı çıkabilir. Biliyorsunuz, Delphi'de float ve double arasında bir fark yok (hatta float diye bir veri tipi bile yok), ama C (ve C++)'de float ve double birbirinden farklı tiplerdir. Eğer siz veri tipini belirmezseniz, variant tipinden dolayı yine float - double arasında bir tercih yapılacaktır. Burada artık iş tamamen gönderilen tarihin değerine kalıyor. Bu arada C'de float 8 byte, double ise 16 bytetır (Yanılıyor olabilirim, tam hatırlamıyorum). Dikkat ederseniz verilerin boyutları yine tutmuyor.

Bu yüzden mrmarman'in dediğini tamamen katılıyorum. Hatta ben bunu sadece datetime tipindeki alanlar için değil, bütün alanlar için belirtiyorum.
Bilgisayarın integeri double (float) olarak yorumlayabileceğini düşünebilirsiniz, ama bu her zaman geçerli olmayabilir.
Aslında temel mantık çok basittir. C, C++ gibi dillerde, fonksiyon parametrelerini referans olarak çağırmak daha yüksek performans demektir, çünkü parametre için bellekte ek bir yer açılmaz. Bu yüzden veri tabanı gibi erişim hızının yüksek olması gereken fonksiyonlarda, parametrelerin referans olarak gönderilmesi çok mantıklıdır. Delphi'de bile kodlarken dikkat ederseniz, var olarak tanımlanmış (yani referans) fonksiyonlarda birebir tutan bir değişken vermeniz istenir. İşte bu yüzden her zaman için geçerli olmayabilir diyorum. Çünkü veri tipleri tutmadığı için veri tabanı motoru yanlış bir fonksiyon ile kıyaslama yapmaya çalışacaktır.

Yazdıklarım tamamen tahmin üzerine kuruludur. Lütfen kimse kesin bilgi olarak düşünmesin. Eğer daha mantıklı ve iyi bir açıklaması olan varsa, buraya yazması, teorik olarak daha zengin bir tartışma başlatacaktır.

Kolay gelsin,
Bahadır Alkaç
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Mesaj gönderen bobasturk »

Merhaba,

@Opt2000 ustam açıklamaların ve bilgi paylaşımın için teşekkür ederim. Burada verdiğim kod satırlarındaki gibi var bloğu içinde parametrelerin alacağı değeri "tarih1, tarih2:tdate;" şeklinde değişkeni tanımlamamız yeterli mi yoksa sorgularda parametreler de yinede tipini belirtmemiz mi gerekmekte.

Teşekkür ve saygılarımla kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Mesaj gönderen Opt2000 »

Selam,

İddia edilen yeterli olduğu, ama benim tavsiyem mrmarman'ın dediği gibi detaylı belirtmek.

Kod: Tümünü seç

dm1.SevkToplamADOQry.Parameters.ParamByName('tarih1').DataType := ftDate;
   dm1.SevkToplamADOQry.Parameters.ParamByName('tarih1').Value:=cxdateedit1.Date;
Bence en doğrusu ve güvenlisi bu.

Kolay gelsin,
Bahadır Alkaç
Cevapla