Mustafa HAMIT

ABAP’ta FOR ALL ENTRIES Kullanımı (Doğru Kullanım, Tuzaklar ve Örnekler)

FOR ALL ENTRIES (FAE), ABAP Open SQL’de bir iç tablodaki (internal table) anahtar değerleri kullanarak veritabanından toplu veri çekmek için kullanılan bir yöntemdir. En çok “elimde bir liste var, bu listedeki anahtarlara göre ikinci tablodan kayıtları çekmem lazım” senaryosunda kullanılır.

Doğru kullanıldığında çok iş görür; yanlış kullanıldığında ise hem performansı düşürür hem de yanlış veri çekmene neden olabilir. Bu yazıda FAE’nin mantığını, en büyük tuzaklarını ve doğru kullanım örneklerini göreceğiz.


1) FOR ALL ENTRIES mantığı nedir?

Temel mantık şudur:

  • Önce bir iç tablo (ör. lt_matnr) elde edersin.
  • Sonra ikinci bir SELECT ile, bu iç tablodaki değerleri “filtre listesi” gibi kullanırsın.
  • ABAP, teknik olarak bunu veritabanına “bu değerlerden herhangi birine uyanları getir” şeklinde iletir.

Basit bir şablon:

SELECT ...
  FROM dbtab
  FOR ALL ENTRIES IN itab
  WHERE keyfield = itab-keyfield
  INTO TABLE ...

2) En büyük tuzak: İç tablo boşsa tüm tabloyu çekme

FAE’nin en kritik kuralı:

Eğer FOR ALL ENTRIES IN lt_xxx dediğin iç tablo BOŞ ise, WHERE koşulu etkisizleşebilir ve SELECT “tüm tabloyu” çekebilir.

Bu yüzden FAE kullanırken neredeyse standart şablon şudur:

IF lt_keys IS NOT INITIAL.
  SELECT ...
    FROM ...
    FOR ALL ENTRIES IN @lt_keys
    WHERE ...
    INTO TABLE @lt_result.
ENDIF.

Bu kontrolü koymamak production ortamında “bir anda milyonlarca kayıt çekme” gibi ciddi sorunlara yol açabilir.


3) Örnek senaryo: MARA’dan materyalleri al, sonra MARC’tan tesis verisini çek

Diyelim ki önce bazı kriterlere göre materyal listesini alıyorsun (MARA), sonra bu materyallerin belirli bir tesisteki (WERKS) verilerini MARC’tan çekmek istiyorsun.

Adım 1: Materyal listesini al

TYPES: BEGIN OF ty_mara_key,
         matnr TYPE mara-matnr,
       END OF ty_mara_key.

DATA lt_matnr TYPE STANDARD TABLE OF ty_mara_key WITH EMPTY KEY.

SELECT matnr
  FROM mara
  INTO TABLE @lt_matnr
  WHERE mtart = @'FERT'
  UP TO 100 ROWS.

Adım 2: FOR ALL ENTRIES ile MARC’tan çek

DATA lt_marc  TYPE STANDARD TABLE OF marc WITH EMPTY KEY.
DATA lv_werks TYPE marc-werks VALUE '1000'.

IF lt_matnr IS NOT INITIAL.

  SELECT matnr,
         werks,
         dispo,
         beskz
    FROM marc
    INTO TABLE @lt_marc
    FOR ALL ENTRIES IN @lt_matnr
    WHERE matnr = @lt_matnr-matnr
      AND werks = @lv_werks.

ENDIF.

Bu yaklaşım özellikle “önce filtreli bir liste çıkar, sonra o listeye göre ikinci tablodan oku” işlerinde çok kullanılır.


4) İkinci tuzak: Tekrarlı (duplicate) anahtarlar

FAE’de iç tablonun içinde aynı anahtar birden fazla kez varsa, veritabanına gereksiz tekrarlar gidebilir. Bu da performansı olumsuz etkileyebilir.

Bu yüzden FAE’den önce anahtar tablosunu deduplicate etmek iyi pratiktir:

SORT lt_matnr BY matnr.
DELETE ADJACENT DUPLICATES FROM lt_matnr COMPARING matnr.

5) Üçüncü tuzak: FAE sonucu da duplicate olabilir

FAE ile çektiğin sonuç setinde de duplicate kayıtlar oluşabilir (özellikle birden fazla alanla ilişki varsa). İhtiyaç durumunda:

  • SELECT DISTINCT kullanmak (her DB’de destek/performans etkisi değişebilir)
  • Sonuç tablosunu SORT + DELETE ADJACENT DUPLICATES ile temizlemek

gerekebilir.


6) FOR ALL ENTRIES mi, JOIN mi?

Genel pratik:

  • Eğer ilişki netse ve tek sorguda çözülebiliyorsa: JOIN genelde daha iyidir.
  • Eğer önce bir liste oluşturman gerekiyor ve bu liste dinamik/karmaşıksa: FOR ALL ENTRIES mantıklı olabilir.

Örnek kıyas:

  • “MARA ile MARC zaten MATNR’dan bağlı, direkt çekebilirim” → JOIN
  • “Önce Z tablosundan bir liste çıkarıyorum, sonra bu listeye göre MARA/MARC okuyacağım” → FAE

7) Performans için ipuçları

  • FAE ile kullanılan WHERE alanlarının (özellikle anahtarların) indeksli olması önemlidir.
  • Çok büyük listelerle FAE kullanıyorsan, listeyi parçalara bölmek (chunk) bazı sistemlerde gerekebilir.
  • Gereksiz alan çekme: SELECT * yerine sadece ihtiyacın olan alanları seç.

Sonuç

FOR ALL ENTRIES, ABAP’ta toplu veri çekmek için güçlü bir araçtır. Ancak doğru kullanılmadığında ciddi performans ve veri doğruluğu problemleri çıkarabilir.

Altın kurallar:

  1. FAE iç tablosu boşsa SELECT çalıştırma (mutlaka kontrol et)
  2. Anahtar tablosunu deduplicate et (SORT + DELETE ADJACENT DUPLICATES)
  3. Mümkünse JOIN kullan, FAE’yi “liste bazlı okuma” senaryolarında tercih et

Loading

Bir yanıt yazın