Die DELETE-Anweisung für interne Tabellen entfernt eine oder mehrere Zeilen aus einer internen Tabelle. Es gibt verschiedene Varianten: Löschen per Index, per Schlüssel, mit WHERE-Bedingung oder das Entfernen von Duplikaten.
Syntax
1. Zeile per Index löschen
DELETE <interne_tabelle> INDEX <index>.2. Zeile per Schlüssel löschen
DELETE TABLE <interne_tabelle> FROM <arbeitsbereich>.DELETE TABLE <interne_tabelle> WITH TABLE KEY <schlüssel> = <wert>.3. Mehrere Zeilen mit WHERE löschen
DELETE <interne_tabelle> WHERE <bedingung>.4. Zeile im aktuellen LOOP löschen
LOOP AT <interne_tabelle> ... DELETE <interne_tabelle>. " Löscht aktuelle ZeileENDLOOP.5. Duplikate entfernen
DELETE ADJACENT DUPLICATES FROM <interne_tabelle> [COMPARING <felder> | ALL FIELDS] [USING KEY <schlüssel>].Systemfelder
Nach DELETE:
-
sy-subrc:0: Mindestens eine Zeile gelöscht4: Keine passende Zeile gefunden
-
sy-tabix: BeiDELETE ... INDEXunverändert; sonst undefiniert
Beispiele
1. Zeile per Index löschen
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Bernd` ) ( `Clara` ) ( `David` ) ).
" Zweite Zeile löschenDELETE lt_names INDEX 2.
" Ergebnis: Anna, Clara, DavidLOOP AT lt_names INTO DATA(lv_name). WRITE: / lv_name.ENDLOOP.2. Erste und letzte Zeile löschen
DATA: lt_data TYPE TABLE OF i.
lt_data = VALUE #( ( 10 ) ( 20 ) ( 30 ) ( 40 ) ( 50 ) ).
" Erste Zeile löschenDELETE lt_data INDEX 1.
" Letzte Zeile löschenDELETE lt_data INDEX lines( lt_data ).
" Ergebnis: 20, 30, 403. Zeile per Schlüssel löschen (FROM)
TYPES: BEGIN OF ty_customer, id TYPE i, name TYPE string, END OF ty_customer.
DATA: lt_customers TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id, ls_customer TYPE ty_customer.
lt_customers = VALUE #( ( id = 1 name = 'Müller' ) ( id = 2 name = 'Schmidt' ) ( id = 3 name = 'Weber' )).
" Kunde mit ID 2 löschenls_customer-id = 2.DELETE TABLE lt_customers FROM ls_customer.
IF sy-subrc = 0. WRITE: / 'Kunde gelöscht.'.ELSE. WRITE: / 'Kunde nicht gefunden.'.ENDIF.4. Zeile per Schlüssel löschen (WITH TABLE KEY)
" Direkter SchlüsselzugriffDELETE TABLE lt_customers WITH TABLE KEY id = 3.
IF sy-subrc = 0. WRITE: / 'Kunde 3 gelöscht.'.ENDIF.5. Mehrere Zeilen mit WHERE löschen
TYPES: BEGIN OF ty_order, order_id TYPE i, status TYPE string, amount TYPE p DECIMALS 2, END OF ty_order.
DATA: lt_orders TYPE TABLE OF ty_order.
lt_orders = VALUE #( ( order_id = 1 status = 'OPEN' amount = '100.00' ) ( order_id = 2 status = 'CANCELLED' amount = '200.00' ) ( order_id = 3 status = 'OPEN' amount = '150.00' ) ( order_id = 4 status = 'CANCELLED' amount = '300.00' ) ( order_id = 5 status = 'COMPLETED' amount = '250.00' )).
" Alle stornierten Bestellungen löschenDELETE lt_orders WHERE status = 'CANCELLED'.
WRITE: / 'Gelöschte Zeilen:', sy-dbcnt.WRITE: / 'Verbleibende Zeilen:', lines( lt_orders ).
" Ergebnis: order_id 1, 3, 5 bleiben6. Komplexe WHERE-Bedingung
" Mehrere Bedingungen kombinierenDELETE lt_orders WHERE status = 'OPEN' AND amount < 120.
" Mit ORDELETE lt_orders WHERE status = 'CANCELLED' OR amount = 0.
" Mit INDATA: lt_status TYPE RANGE OF string.lt_status = VALUE #( ( sign = 'I' option = 'EQ' low = 'CANCELLED' ) ( sign = 'I' option = 'EQ' low = 'REJECTED' ) ).
DELETE lt_orders WHERE status IN lt_status.7. Zeile im LOOP löschen
" ACHTUNG: DELETE im LOOP ist erlaubt, aber Vorsicht bei Field-Symbols!
DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ( 6 ) ).
" Alle geraden Zahlen löschenLOOP AT lt_numbers INTO DATA(lv_num). IF lv_num MOD 2 = 0. DELETE lt_numbers. ENDIF.ENDLOOP.
" Ergebnis: 1, 3, 58. DELETE im LOOP mit ASSIGNING (Vorsicht!)
" Mit ASSIGNING ist DELETE problematisch!LOOP AT lt_numbers ASSIGNING FIELD-SYMBOL(<fs_num>). IF <fs_num> MOD 2 = 0. DELETE lt_numbers. " ACHTUNG: <fs_num> zeigt jetzt auf ungültige Daten! " Weitere Zugriffe auf <fs_num> können Fehler verursachen. ENDIF.ENDLOOP.
" BESSER: Mit INTO arbeiten oder WHERE verwendenDELETE lt_numbers WHERE table_line MOD 2 = 0.9. DELETE ADJACENT DUPLICATES - Duplikate entfernen
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Anna` ) ( `Bernd` ) ( `Clara` ) ( `Clara` ) ( `Clara` ) ( `David` )).
" Aufeinanderfolgende Duplikate entfernenDELETE ADJACENT DUPLICATES FROM lt_names.
" Ergebnis: Anna, Bernd, Clara, DavidLOOP AT lt_names INTO DATA(lv_name). WRITE: / lv_name.ENDLOOP.10. DELETE ADJACENT DUPLICATES nach SORT
TYPES: BEGIN OF ty_product, category TYPE string, name TYPE string, price TYPE p DECIMALS 2, END OF ty_product.
DATA: lt_products TYPE TABLE OF ty_product.
lt_products = VALUE #( ( category = 'A' name = 'Prod1' price = 10 ) ( category = 'B' name = 'Prod2' price = 20 ) ( category = 'A' name = 'Prod3' price = 15 ) ( category = 'A' name = 'Prod1' price = 10 ) " Duplikat ( category = 'B' name = 'Prod2' price = 25 ) " Teilweise Duplikat).
" WICHTIG: Erst sortieren!SORT lt_products BY category name.
" Duplikate nach category und name entfernenDELETE ADJACENT DUPLICATES FROM lt_products COMPARING category name.
" Ergebnis: Nur eindeutige category/name Kombinationen11. COMPARING ALL FIELDS
" Nur exakte Duplikate entfernen (alle Felder gleich)SORT lt_products BY category name price.
DELETE ADJACENT DUPLICATES FROM lt_products COMPARING ALL FIELDS.12. USING KEY für Sekundärschlüssel
DATA: lt_data TYPE SORTED TABLE OF ty_product WITH UNIQUE KEY category name WITH NON-UNIQUE SORTED KEY by_price COMPONENTS price.
" Duplikate nach Preis entfernenDELETE ADJACENT DUPLICATES FROM lt_data USING KEY by_price.13. Bereich löschen (FROM … TO)
DATA: lt_nums TYPE TABLE OF i.
lt_nums = VALUE #( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ( 6 ) ( 7 ) ( 8 ) ).
" Zeilen 3 bis 6 löschenDELETE lt_nums FROM 3 TO 6.
" Ergebnis: 1, 2, 7, 814. DELETE für verschiedene Tabellentypen
| Tabellentyp | INDEX | FROM wa | WITH TABLE KEY | WHERE |
|---|---|---|---|---|
| STANDARD | Ja | Ja (linear) | Ja | Ja |
| SORTED | Ja | Ja (binär) | Ja | Ja |
| HASHED | Nein | Ja (hash) | Ja | Ja |
" STANDARD TABLE: Alle Varianten möglichDATA: lt_standard TYPE STANDARD TABLE OF ty_customer.DELETE lt_standard INDEX 1.DELETE TABLE lt_standard FROM ls_customer.DELETE lt_standard WHERE name = 'Test'.
" HASHED TABLE: Kein INDEX!DATA: lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id." DELETE lt_hashed INDEX 1. " FEHLER!DELETE TABLE lt_hashed WITH TABLE KEY id = 1. " OKDELETE lt_hashed WHERE name = 'Test'. " OKVergleich: DELETE vs. CLEAR vs. FREE
| Anweisung | Wirkung |
|---|---|
DELETE itab ... | Entfernt bestimmte Zeilen |
CLEAR itab | Entfernt alle Zeilen, behält Speicher |
FREE itab | Entfernt alle Zeilen, gibt Speicher frei |
" Bestimmte Zeilen entfernenDELETE lt_data WHERE status = 'X'.
" Alle Zeilen entfernen (Speicher behalten)CLEAR lt_data.
" Alle Zeilen entfernen und Speicher freigebenFREE lt_data.Performance-Tipps
-
WHERE statt LOOP mit DELETE:
" LANGSAMLOOP AT lt_data INTO ls_data.IF ls_data-status = 'X'.DELETE lt_data.ENDIF.ENDLOOP." SCHNELLERDELETE lt_data WHERE status = 'X'. -
SORT vor ADJACENT DUPLICATES:
DELETE ADJACENT DUPLICATESerkennt nur aufeinanderfolgende Duplikate. Sortieren Sie zuerst! -
Index-basiertes Löschen von hinten:
" Beim Löschen mehrerer Zeilen per Index: Von hinten nach vorneDO 3 TIMES.DELETE lt_data INDEX lines( lt_data ).ENDDO. -
Effiziente Massenloschung: Für das Löschen vieler Zeilen ist
DELETE ... WHEREeffizienter als einzelne Löschungen.
Wichtige Hinweise / Best Practice
- Prüfen Sie
sy-subrcnachDELETE ... INDEXoderDELETE TABLE. DELETE ... WHEREsetztsy-subrc = 0auch wenn keine Zeile gelöscht wurde (abersy-dbcnt = 0).- Sortieren Sie vor
DELETE ADJACENT DUPLICATES. - Vorsicht beim Löschen im
LOOP ATmitASSIGNING– das Field-Symbol wird ungültig! - Bei
HASHED TABLEistDELETE ... INDEXnicht möglich. - Für Datenbanktabellen verwenden Sie
DELETE FROM dbtab. DELETE ADJACENT DUPLICATESentfernt nur benachbarte Duplikate.- Nutzen Sie
SORTin Kombination mitDELETE ADJACENT DUPLICATESfür eindeutige Listen.