Prior ve Locate kayıt arama ve konumlanma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
delphist
Üye
Mesajlar: 595
Kayıt: 05 Oca 2005 04:34

Prior ve Locate kayıt arama ve konumlanma

Mesaj gönderen delphist »

Selamlar. Arkadaşlar bazı durumlardan dolayı tabloyu ters aramam gerekiyor. Kayıta locate ile konumlanıyorum.

while not a.bof begin



end;

a.prior;

şeklinde kayıt geriden bakılıyor fakat ilk önce bir kayda konumlanmam gerekiyor...Tablonun durumu tam olarak mantık olarak aşağıdaki gibi

0
1
2
3
3
3
3
3
3
2
2
3
2
2
2
2
2
2
2
2



Örneğin aradığım kayıt 3 İlk önce 3 konumlandığım zaman tabi kayıtın ismi ile konumlanıyorum. 3 e konumladıktan sonra ilk 2 sonra ilk 1 nolu kayıtı sonra ilk 0 nolu kaydı bulmam lazım. Bunun içinde aşağıdan yukarı doğru böle bir sorgu yapmam gerekiyor...Ama belki mantığıma ters geldi locate ile aradığım zaman üstten arayıp geldiğ için aradaki farklı kayıdı buluyor...

Cevaplarınız için şimdiden teşekkür ediyorum. Bu konuda fikir, mantık ve yol yordamlarınıza ihtiyacım var.
ertug
Üye
Mesajlar: 82
Kayıt: 10 Ara 2004 05:41

Mesaj gönderen ertug »

Merhaba,

Locate, ilk bulduğu kaydın üzerine gidecektir. Sizin için sunabileceğim, aklıma ilk gelen çözümler:

1. SQL kullanabilirsiniz.
2. Bir view oluşturup oradan locate yapabilirsiniz.
3. Tabloyu ters sıralayacak şekilde bir index oluşturabilirsiniz. Böylece Locate doğru kayıdı getirecektir. Ancak döngülerinizdeki priorları, next ile değiştirmeniz gerekecektir.
4. Filtre kullanabilirsiniz. Filtreledikten sonra son kayda gidebilirsiniz.

Veritabanınızın ne olduğunu belirtmemişsiniz. Eğer MS SQL Server, Oracle, MySQL, FB gibi bir vt kullanıyorsanız, ben olsam Locate kullanmazdım. SQL her zaman daha iyi ve hızlı sonuç verecektir. Özellikle döngü içerisinde çok sayıda arama yapıyorsanız kesinlikle batch modunda (Kilit türü: BatchOptimistic) SQL kullanın.

Ertuğ Kaya
Kullanıcı avatarı
delphist
Üye
Mesajlar: 595
Kayıt: 05 Oca 2005 04:34

Mesaj gönderen delphist »

Evet Mssql Server Kullanıyorum. Bu arada fikirleriniz için gerçekten teşekkür ederim. Fakat şu batch olayını bi açabilirmisiniz...Biraz öğrenmek istiyorum. Dediğinizi anlayamadım...Teşekkürler
ertug
Üye
Mesajlar: 82
Kayıt: 10 Ara 2004 05:41

Mesaj gönderen ertug »

Birşey değil. Söylediklerimi biraz daha açayım. Bağlantıyı standart ADO nesneleri ile yapıyorsanız, şunu deneyebilirsiniz:

DataModule üzerine bir adet ADOQuery koyun. Özelliklerinin içerisinde LockType'ı bulun. Bunu ltBatchOptimistic yapın.

Batch optimistik kilit türü, özel bir türdür. Yazma işlemleri tek tek yapılmaz, biriktirilerek toplu halde yapılır. Özellikle döngü içerisindeki "update" komutlarında inanılmaz hız artışı sağlar. Okuma konusunda da genelde daha iyi sonuçlar verdiğini tecrübe ettim. En iyisi deneyip kendi veritabanınız için en iyi veren sonucu bulmanızdır.

Okuma konusunda bir başka boyut daha vardır. SQL Server'ın kendi "cache"i olduğundan kısa bir süre sonra okuma hızı maksimuma ulaşacaktır. Bunun için sunucuya 2 GB takmanızı öneririm.

"Cache"i basitçe, işlemleri hızlandırmak için kullanılan tampon bellek veya bölge olarak düşünebilirsiniz.

Ertuğ Kaya
Değiştirme: 2 GB *bellek* demek istedim.
Kullanıcı avatarı
delphist
Üye
Mesajlar: 595
Kayıt: 05 Oca 2005 04:34

Mesaj gönderen delphist »

Normalde şöyle bir olay yapabilseydim locate ilede halledebilecektim..olayı...Neden Çünkü arama yaptığım zaman kayıt ilk kayda konumlandırdığım zaman diğer kaydı konumlattıracağımda yani. örneğin 3 buldum diyelim 2 yi bulacam 2 yi bulmak için 3 den başlaması gerekmeli...Eğer böyle bir şey yapılabiliyorsa bu da benim işimi görür...ama Locate de de şöyle bir problemim var onuda yazim...

if adoquery2.Locate('PERSONEL_KODU', edit2.Text, []) then
begin
Kayıdı buluyoruz ama bu seferde kaydı hareket ettirmem gerekiyor ettiremiyorum normalde eğer böle bi kayıt varsa bulduktan. döngünün hareket etmesi lazım böle bir şey yapmam lazım ayrıca sql ile de yapmak isterim ama sql le de tabloyu tamamen filtrelediği için diğer kayıtlara gitmem lazım ama gidemiyorum.

ADOQuery2.Close;
adoquery2.SQL.Clear;
adoquery2.SQL.Add('SELECT * FROM PERSONEL');
adoquery2.SQL.Add('WHERE PERSONEL_KODU ='+QuotedStr(Edit2.Text)+'');
ADOQuery2.Active:=true;
Bu şekilde sadece bana kayıta datasource konumlanması yeterli ama filtreliyor ben filtrelemesini istemiyorum. sadece kayıt ilk kayıt nosunun yanındaki noyu alarak diğer noyu bulmayı daha sonra diğer noyu bulmayı istiyorum.
ertug
Üye
Mesajlar: 82
Kayıt: 10 Ara 2004 05:41

Mesaj gönderen ertug »

Anladığım kadarıyla Locate komutunu bir ADOTable üzerinden çalıştırıyorsunuz. Eğer "SQL"e girmek istemiyorsanız 2. önerim olan view oluşturma seçeneğini deneyin. Ancak bu "view"da sıralamayı ters yapın. "Locate"i de view üzerinden yapın. Böylece Locate en sondaki 3ü bulacaktır. Ancak dediğim gibi hareket komutlarınızı da "Prior"dan -> "Next"e değiştirmeniz gerekmektedir.

Ertuğ Kaya
Kullanıcı avatarı
delphist
Üye
Mesajlar: 595
Kayıt: 05 Oca 2005 04:34

Mesaj gönderen delphist »

Yok Hayır şimdiye kadar hiç adotable kullanmadım. Hep datasetle çalışıyorum ve genellikle kayıtları sp lerle yapıyorum ve genel olarak hiyerşiyi de triggerlarla kuruyorum fk kullanmıyorum ve bunun gibi şeyler. + Bu arada view larda order by ifadesini kullanamıyorsun...

Şöyle söyleyim bi kayıta locate olduktan sonra bundan sonra uygulanacak locatein en son locate olunan kayıttan devam etmesi istiyordum...Ama mümkünmü değil mi mümkünse zaten arkadaşlar cevaplarını verecektir. Yani istememin sebebi dışardan parametre alınan değerden aramaya gidildiği zaman bulunan kaydın altındaki ilk 3 veya ilk 2 ve daha sonra ilk 1 ama locate tekrar tablonun üzerinden arama yaptığı için arada başka 3 varsa onu bulmuş oluyor ve tabide tutarsız oluyor....

Ben şöle çözdüm kayıt ederken bu kayıtlara bir de id girdim kayıt ederken. autoinc olan bi id alanı yani. Kayda locate olduktan sonra o kaydın nosunu ve idsini aldım daha sonra bi while ile kayıt nosu 9 dan mesela küçük olan seviye de 4 den küçük olan dediğin zaman otomatikman istediğim kayıta ulaştım... :) Ama hala locate ile kayıt bulunduktan sonra tekrar locate edildiği zaman başka bir kayda en son bulunan değerden ulaşılabiliyor mu bilmiyorum...

İyi Çalışmalar...Yardımlarınız için Teşekkür ederim
ertug
Üye
Mesajlar: 82
Kayıt: 10 Ara 2004 05:41

Mesaj gönderen ertug »

delphist yazdı: + Bu arada view larda order by ifadesini kullanamıyorsun...
Haklısınız, sanırım eski sürümlerde yapabiliyordunuz veya ben öyle hatırlıyorum :(. Yaptığım "view"lara bakınca, Order By kullandıklarımda select kısmında TOP ile beraber kullandığımı gördüm. Zaten öyle yapmazsanız hata veriyor.
delphist yazdı:Şöyle söyleyim bi kayıta locate olduktan sonra bundan sonra uygulanacak locatein en son locate olunan kayıttan devam etmesi istiyordum...Ama mümkünmü değil mi mümkünse zaten arkadaşlar cevaplarını verecektir.
MS SQLdeki örnek veritabanlarından Northwind.Orders için deneme yapabiliriz:

Kod: Tümünü seç

  //ilk EmployeeID = 8 olan kayda gitmek için
  ADOTable1.Filter := 'EmployeeID = 8'; //Dikkat: Filtered := True yapmak zorunda değiliz!
  ADOTable1.FindFirst;

Kod: Tümünü seç

  //sonraki EmployeeID = 8 olan kayda gitmek için
  ADOTable1.FindNext;
FindLast ve FindPrior da kullanabilirsiniz.

Bu yöntem D6 "ADOTable"da çalışıyor. Diğer datasetlerle de çalışacaktır.

Ertuğ Kaya
Cevapla