Select for all entries
Siehe Schlüsselbefehl Select.
Eine interessante Alternative zu einem Range, bzw. Select-Options bei einer Select-Abfrage oder einem geschachtelten Loop-Select-Endloop ist der Befehl "FOR ALL ENTRIES".
Dieser Befehl ist auch deutlich performanter als wenn man über eine Tabelle loopt und innerhalb des Loops jeweils ein Select-Single.
Siehe SAP-Hilfe: For all entries und Tricktresor: For all entries.
In der Auflösung auf Datenbankebene verhält sich der Befehl „for all entries“ etwas anders als ein Range/Select-Options. Siehe hierzu https://www.dpunkt.de/common/leseproben//10992/Abschnitt_4.4.pdf, S. 181 ff.. Der Befehl „for all entries“ soll langsamer sein als ein vergleichbarer Range.
Coding
select * from sbook
into table lt_bookings
where customid = p_custid
and carrid in s_carrid
order by primary key.
if lt_bookings is not initial.
select * from spfli
into table lt_connections
for all entries in lt_bookings
where carrid = lt_bookings-carrid
and connid = lt_bookings-connid
order by primary key.
endif.
Zur Vorsicht bei Nutzung "Select for all entries"
interne Tabelle ist nicht gefüllt
Wenn die interne Tabelle bei "for all entries" leer ist, erfolgt keine Einschränkung über die Where-Felder. Das wird praktisch nie gewünscht sein. Daher wird es in aller Regel sinnvoll sein ein Coding einzubauen
if lt_itab is not initial. ... endif.
Laufzeitfehler bei sehr vielen Datensätzen in interner Tabelle
- Wenn die interne Tabelle bei "for all entries" sehr viele Datensätze enthält, kann es auch zu einem Laufzeitfehler kommen.
- Bei aktuellen Datenbanken hat sich dieses Problem entschärft. Hier ist nur die Größe der Systemtabelle beschränkt, siehe SAP-Hilfe zum "select for all entries"
Eleminierung von doppelten Datensätzen
- Doppelte Datensätze werden aus der Ergebnismenge gelöscht. Das muss nicht immer gewünscht sein, wenn z. B über bestimmte Felder der Ergebnismenge (z. B. Liefermenge) eine Summe gezogen wird.
- Siehe https://tricktresor.de/blog/vorsicht-bei-for-all-entries/.
Lesen eines Satzes bei "Select for all entries" in itab
- Da N Sätze beim "for all entries" abgearbeitet werden, wird die Zielmenge auch in aller Regel in eine interne Tabelle gehen
- Wenn nur ein Datensatz gefunden werden soll, dann kann man sich bei einer Select-Endselect-Schleife mit dem Zusatz "up to 1 rows" behelfen
IF lt_kunn2 IS NOT INITIAL.
SELECT
knvp~kunn2
INTO lv_kunnr_mf
FROM knvp
INNER JOIN knvv
ON knvv~kunnr = knvp~kunn2
AND knvv~vkorg = knvp~vkorg
AND knvv~vtweg = knvp~vtweg
AND knvv~spart = knvp~spart
UP TO 1 ROWS
FOR ALL ENTRIES IN lt_kunn2
WHERE knvp~kunnr = lt_kunn2-kunn2
AND knvp~parvw = lc_parvw_mf
AND knvv~kvgr3 = lv_pr_line.
ENDSELECT.
if sy-subrc <> 0.
...
endif.
ENDIF.