La sentencia DELETE para tablas internas elimina una o mas filas de una tabla interna. Existen diferentes variantes: eliminar por indice, por clave, con condicion WHERE o eliminar duplicados.
Sintaxis
1. Eliminar fila por indice
DELETE <tabla_interna> INDEX <indice>.2. Eliminar fila por clave
DELETE TABLE <tabla_interna> FROM <area_trabajo>.DELETE TABLE <tabla_interna> WITH TABLE KEY <clave> = <valor>.3. Eliminar multiples filas con WHERE
DELETE <tabla_interna> WHERE <condicion>.4. Eliminar fila en el LOOP actual
LOOP AT <tabla_interna> ... DELETE <tabla_interna>. " Elimina fila actualENDLOOP.5. Eliminar duplicados
DELETE ADJACENT DUPLICATES FROM <tabla_interna> [COMPARING <campos> | ALL FIELDS] [USING KEY <clave>].Campos del sistema
Despues de DELETE:
-
sy-subrc:0: Al menos una fila eliminada4: No se encontro ninguna fila coincidente
-
sy-tabix: EnDELETE ... INDEXsin cambio; de lo contrario indefinido
Ejemplos
1. Eliminar fila por indice
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Ana` ) ( `Bernardo` ) ( `Clara` ) ( `David` ) ).
" Eliminar segunda filaDELETE lt_names INDEX 2.
" Resultado: Ana, Clara, DavidLOOP AT lt_names INTO DATA(lv_name). WRITE: / lv_name.ENDLOOP.2. Eliminar primera y ultima fila
DATA: lt_data TYPE TABLE OF i.
lt_data = VALUE #( ( 10 ) ( 20 ) ( 30 ) ( 40 ) ( 50 ) ).
" Eliminar primera filaDELETE lt_data INDEX 1.
" Eliminar ultima filaDELETE lt_data INDEX lines( lt_data ).
" Resultado: 20, 30, 403. Eliminar fila por clave (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 = 'Muller' ) ( id = 2 name = 'Schmidt' ) ( id = 3 name = 'Weber' )).
" Eliminar cliente con ID 2ls_customer-id = 2.DELETE TABLE lt_customers FROM ls_customer.
IF sy-subrc = 0. WRITE: / 'Cliente eliminado.'.ELSE. WRITE: / 'Cliente no encontrado.'.ENDIF.4. Eliminar fila por clave (WITH TABLE KEY)
" Acceso directo por claveDELETE TABLE lt_customers WITH TABLE KEY id = 3.
IF sy-subrc = 0. WRITE: / 'Cliente 3 eliminado.'.ENDIF.5. Eliminar multiples filas con WHERE
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' )).
" Eliminar todos los pedidos canceladosDELETE lt_orders WHERE status = 'CANCELLED'.
WRITE: / 'Filas eliminadas:', sy-dbcnt.WRITE: / 'Filas restantes:', lines( lt_orders ).
" Resultado: order_id 1, 3, 5 quedan6. Condicion WHERE compleja
" Combinar multiples condicionesDELETE lt_orders WHERE status = 'OPEN' AND amount < 120.
" Con ORDELETE lt_orders WHERE status = 'CANCELLED' OR amount = 0.
" Con 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. Eliminar fila en LOOP
" ATENCION: DELETE en LOOP esta permitido, pero cuidado con Field-Symbols!
DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ( 6 ) ).
" Eliminar todos los numeros paresLOOP AT lt_numbers INTO DATA(lv_num). IF lv_num MOD 2 = 0. DELETE lt_numbers. ENDIF.ENDLOOP.
" Resultado: 1, 3, 58. DELETE en LOOP con ASSIGNING (Cuidado!)
" Con ASSIGNING, DELETE es problematico!LOOP AT lt_numbers ASSIGNING FIELD-SYMBOL(<fs_num>). IF <fs_num> MOD 2 = 0. DELETE lt_numbers. " ATENCION: <fs_num> ahora apunta a datos invalidos! " Accesos adicionales a <fs_num> pueden causar errores. ENDIF.ENDLOOP.
" MEJOR: Trabajar con INTO o usar WHEREDELETE lt_numbers WHERE table_line MOD 2 = 0.9. DELETE ADJACENT DUPLICATES - Eliminar duplicados
DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Ana` ) ( `Ana` ) ( `Bernardo` ) ( `Clara` ) ( `Clara` ) ( `Clara` ) ( `David` )).
" Eliminar duplicados consecutivosDELETE ADJACENT DUPLICATES FROM lt_names.
" Resultado: Ana, Bernardo, Clara, DavidLOOP AT lt_names INTO DATA(lv_name). WRITE: / lv_name.ENDLOOP.10. DELETE ADJACENT DUPLICATES despues de 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 ) " Duplicado ( category = 'B' name = 'Prod2' price = 25 ) " Duplicado parcial).
" IMPORTANTE: Primero ordenar!SORT lt_products BY category name.
" Eliminar duplicados por category y nameDELETE ADJACENT DUPLICATES FROM lt_products COMPARING category name.
" Resultado: Solo combinaciones unicas category/name11. COMPARING ALL FIELDS
" Eliminar solo duplicados exactos (todos los campos iguales)SORT lt_products BY category name price.
DELETE ADJACENT DUPLICATES FROM lt_products COMPARING ALL FIELDS.12. USING KEY para clave secundaria
DATA: lt_data TYPE SORTED TABLE OF ty_product WITH UNIQUE KEY category name WITH NON-UNIQUE SORTED KEY by_price COMPONENTS price.
" Eliminar duplicados por precioDELETE ADJACENT DUPLICATES FROM lt_data USING KEY by_price.13. Eliminar rango (FROM … TO)
DATA: lt_nums TYPE TABLE OF i.
lt_nums = VALUE #( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ( 6 ) ( 7 ) ( 8 ) ).
" Eliminar filas 3 a 6DELETE lt_nums FROM 3 TO 6.
" Resultado: 1, 2, 7, 814. DELETE para diferentes tipos de tabla
| Tipo de tabla | INDEX | FROM wa | WITH TABLE KEY | WHERE |
|---|---|---|---|---|
| STANDARD | Si | Si (lineal) | Si | Si |
| SORTED | Si | Si (binario) | Si | Si |
| HASHED | No | Si (hash) | Si | Si |
" STANDARD TABLE: Todas las variantes posiblesDATA: 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: Sin INDEX!DATA: lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id." DELETE lt_hashed INDEX 1. " ERROR!DELETE TABLE lt_hashed WITH TABLE KEY id = 1. " OKDELETE lt_hashed WHERE name = 'Test'. " OKComparacion: DELETE vs. CLEAR vs. FREE
| Sentencia | Efecto |
|---|---|
DELETE itab ... | Elimina filas especificas |
CLEAR itab | Elimina todas las filas, mantiene memoria |
FREE itab | Elimina todas las filas, libera memoria |
" Eliminar filas especificasDELETE lt_data WHERE status = 'X'.
" Eliminar todas las filas (mantener memoria)CLEAR lt_data.
" Eliminar todas las filas y liberar memoriaFREE lt_data.Consejos de rendimiento
-
WHERE en lugar de LOOP con DELETE:
" LENTOLOOP AT lt_data INTO ls_data.IF ls_data-status = 'X'.DELETE lt_data.ENDIF.ENDLOOP." MAS RAPIDODELETE lt_data WHERE status = 'X'. -
SORT antes de ADJACENT DUPLICATES:
DELETE ADJACENT DUPLICATESsolo reconoce duplicados consecutivos. Ordena primero! -
Eliminacion basada en indice desde atras:
" Al eliminar multiples filas por indice: de atras hacia adelanteDO 3 TIMES.DELETE lt_data INDEX lines( lt_data ).ENDDO. -
Eliminacion masiva eficiente: Para eliminar muchas filas,
DELETE ... WHEREes mas eficiente que eliminaciones individuales.
Notas importantes / Mejores practicas
- Verifica
sy-subrcdespues deDELETE ... INDEXoDELETE TABLE. DELETE ... WHEREestablecesy-subrc = 0incluso si no se elimino ninguna fila (perosy-dbcnt = 0).- Ordena antes de
DELETE ADJACENT DUPLICATES. - Cuidado al eliminar en
LOOP ATconASSIGNING- el Field-Symbol se vuelve invalido! - En
HASHED TABLEno es posibleDELETE ... INDEX. - Para tablas de base de datos usa
DELETE FROM dbtab. DELETE ADJACENT DUPLICATESsolo elimina duplicados adyacentes.- Usa
SORTen combinacion conDELETE ADJACENT DUPLICATESpara listas unicas.