Döngü kurmadan tek bir satır bulmak

Bir önceki yazıda tablo üzerinde gezinmenin (LOOP AT) farklı performans sınıflarına değinmiştim. Ama bazen amacınız tüm satırları gezmek değil, sadece tek bir eşleşen satırı bulmaktır — bu durumda döngü kurmak gereksiz bir ek yüktür. TROIA bunun için ayrı bir komut ailesi sunuyor: LOCATERECORD.

Üç arama modu

Sıralı arama — tabloyu baştan sona tarar, en yavaş ama her koşulda çalışan seçenek:

LOCATERECORD SEQUENTIAL COLUMNS {kolonlar} VALUES {degerler} ON {tablo};

İkili arama — tablo aranan kolona göre önceden sıralanmışsa kullanılabilir, sıralı aramadan çok daha hızlıdır:

LOCATERECORD BINARYSEARCH COLUMNS {kolonlar} VALUES {degerler} ON {tablo};

Index'li arama — önceden kurulmuş bir hash index üzerinden arar, tekrarlı aramalarda en hızlı seçenektir:

BUILDHASHINDEX {indeksadi} COLUMNS {kolonlar} ON {tablo};
LOCATERECORD INDEXED INDEX {indeksadi} VALUES {degerler} ON {tablo};

Bulunan satır otomatik olarak tablonun aktif satırı (_ACTIVEROW) haline gelir; bulunamazsa aktif satır değişmez ya da geçersiz bir duruma düşer — bu yüzden LOCATERECORD'dan sonra sonucu her zaman kontrol etmek gerekir.

Gerçek bir örnek: ürün kodundan tek kayıt bulmak

/* Ürün tablosunda belirli bir kodu arar, bulamazsa uyarı verir. */
LOCAL:
    TABLE URUNLER(KOD CHAR(20), ADI CHAR(100), STOK DECIMAL);

SELECT KOD, ADI, STOK FROM URUN_KARTI INTO URUNLER;

LOCATERECORD SEQUENTIAL COLUMNS 'KOD' VALUES ARANANKOD ON URUNLER;

IF RETURNVALUE == 'notfound' THEN
    MESSAGE 'Ürün bulunamadı: ' + ARANANKOD TYPE WARNING;
ELSE
    MESSAGE 'Stok miktarı: ' + URUNLER_STOK TYPE INFORMATION;
ENDIF;

Hangi modu ne zaman seçmeli

  • Tablo küçük ya da arama bir kereliğine yapılıyorsa: SEQUENTIAL yeterlidir, ekstra hazırlık maliyeti gerektirmez.
  • Tablo zaten aranan kolona göre sıralıysa (örneğin SORT ile önceden sıralanmışsa): BINARYSEARCH ek bir yapı kurmadan hızlı sonuç verir.
  • Aynı tabloda tekrar tekrar, farklı değerlerle arama yapılacaksa: INDEXED — kurulum maliyetini bir kez ödeyip sonraki her aramada kazanırsınız.

Sık yapılan hatalar

  • Sıralı olmayan bir tabloda BINARYSEARCH kullanmak — ikili arama, verinin gerçekten aranan kolona göre sıralı olduğunu varsayar; sıralanmamış bir tabloda kullanılırsa yanlış ya da tutarsız sonuçlar alırsınız. BINARYSEARCH'ten önce ilgili kolona göre SORT çağrıldığından emin olun.
  • Bulunamama durumunu kontrol etmemek — LOCATERECORD başarısız olduğunda aktif satır güncellenmez; bunu fark etmeden bir önceki aramadan kalan aktif satırın verisini "yeni bulunmuş" gibi kullanmak, sessiz ve teşhisi zor bir hataya yol açar. RETURNVALUE (ya da ortamınızdaki karşılığı) her zaman kontrol edilmeli.
  • Tek seferlik bir arama için hash index kurmak — BUILDHASHINDEX'in kendi maliyeti var; bir transaction'da bir kez çalışacak bir arama için index kurmak, sıralı aramadan daha yavaş olabilir.
  • Index'i tablo güncellendikten sonra yeniden kurmamak — tabloya yeni satır eklendiyse ya da veriler değiştiyse, eski index üzerinden yapılan LOCATERECORD INDEXED güncel olmayan sonuçlar verebilir.

Sıradaki adım

Bir sonraki yazıda class'lara dönüp, _VARIABLES/_CONSTRUCTOR özel metodlarını ve THIS ile @ operatörünün ne işe yaradığını ele alacağım.