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
SELECTile, 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 DISTINCTkullanmak (her DB’de destek/performans etkisi değişebilir)- Sonuç tablosunu
SORT+DELETE ADJACENT DUPLICATESile 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
WHEREalanları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:
- FAE iç tablosu boşsa
SELECTçalıştırma (mutlaka kontrol et) - Anahtar tablosunu deduplicate et (
SORT+DELETE ADJACENT DUPLICATES) - Mümkünse
JOINkullan, FAE’yi “liste bazlı okuma” senaryolarında tercih et
![]()