ABAP INSERT para tablas internas: Insertar filas

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

La sentencia INSERT para tablas internas inserta una o más filas en una posición específica o según la clave de tabla. A diferencia de APPEND, que siempre añade al final, INSERT permite un control preciso sobre la posición de inserción.

Sintaxis

1. Insertar fila por índice

INSERT <fila> INTO <tabla_interna> INDEX <indice>.

2. Insertar fila según clave

INSERT <fila> INTO TABLE <tabla_interna>.

3. Insertar múltiples filas

INSERT LINES OF <tabla_origen> INTO TABLE <tabla_destino>.
INSERT LINES OF <tabla_origen> FROM <desde> TO <hasta> INTO <tabla_destino> INDEX <indice>.

4. Insertar fila inicial

INSERT INITIAL LINE INTO <tabla_interna> INDEX <indice>.
INSERT INITIAL LINE INTO TABLE <tabla_interna>.

Campos del sistema

Después de INSERT:

  • sy-subrc:

    • 0: Fila insertada exitosamente
    • 4: No se pudo insertar la fila (p. ej., duplicado con UNIQUE KEY)
  • sy-tabix: Índice de la fila insertada (en variante INDEX)

Ejemplos

1. Insertar fila por índice

DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Clara` ) ( `David` ) ).
" Insertar Bernd en posición 2
INSERT `Bernd` INTO lt_names INDEX 2.
" Resultado: Anna, Bernd, Clara, David
LOOP AT lt_names INTO DATA(lv_name).
WRITE: / sy-tabix, lv_name.
ENDLOOP.

2. Insertar al principio

DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 2 ) ( 3 ) ( 4 ) ).
" Insertar 1 al principio
INSERT 1 INTO lt_numbers INDEX 1.
" Resultado: 1, 2, 3, 4

3. Insertar estructura

TYPES: BEGIN OF ty_customer,
id TYPE i,
name TYPE string,
city TYPE string,
END OF ty_customer.
DATA: lt_customers TYPE TABLE OF ty_customer,
ls_customer TYPE ty_customer.
lt_customers = VALUE #(
( id = 1 name = 'Müller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Insertar nuevo cliente en posición 2
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'München' ).
INSERT ls_customer INTO lt_customers INDEX 2.
" Resultado: Müller (1), Schmidt (2), Weber (3)

4. INSERT INTO TABLE (según clave)

DATA: lt_sorted TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_sorted = VALUE #(
( id = 1 name = 'Müller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Se inserta automáticamente en la posición correcta (ordenado por clave)
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'München' ).
INSERT ls_customer INTO TABLE lt_sorted.
IF sy-subrc = 0.
WRITE: / 'Insertado exitosamente en posición:', sy-tabix.
ENDIF.
" Resultado: Insertado automáticamente entre ID 1 y 3

5. Evitar duplicados (UNIQUE KEY)

DATA: lt_unique TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_unique = VALUE #( ( id = 1 name = 'Müller' city = 'Berlin' ) ).
" Intento de insertar duplicado
ls_customer = VALUE #( id = 1 name = 'Nuevo' city = 'Köln' ).
INSERT ls_customer INTO TABLE lt_unique.
IF sy-subrc = 4.
WRITE: / '¡Duplicado! Fila no insertada.'.
ENDIF.

6. HASHED TABLE

DATA: lt_hashed TYPE HASHED TABLE OF ty_customer
WITH UNIQUE KEY id.
" Para HASHED TABLE: Siempre INSERT INTO TABLE (¡sin INDEX!)
ls_customer = VALUE #( id = 5 name = 'Bauer' city = 'Dresden' ).
INSERT ls_customer INTO TABLE lt_hashed.
IF sy-subrc = 0.
WRITE: / 'Insertado en tabla hash.'.
ENDIF.

7. Insertar múltiples filas (LINES OF)

DATA: lt_source TYPE TABLE OF string,
lt_target TYPE TABLE OF string.
lt_source = VALUE #( ( `Nuevo1` ) ( `Nuevo2` ) ( `Nuevo3` ) ).
lt_target = VALUE #( ( `Antiguo1` ) ( `Antiguo2` ) ).
" Insertar todas las filas de source en target (al final)
INSERT LINES OF lt_source INTO TABLE lt_target.
" Resultado: Antiguo1, Antiguo2, Nuevo1, Nuevo2, Nuevo3

8. LINES OF con INDEX

DATA: lt_source TYPE TABLE OF string,
lt_target TYPE TABLE OF string.
lt_source = VALUE #( ( `X` ) ( `Y` ) ( `Z` ) ).
lt_target = VALUE #( ( `A` ) ( `B` ) ( `C` ) ).
" Insertar filas en posición 2
INSERT LINES OF lt_source INTO lt_target INDEX 2.
" Resultado: A, X, Y, Z, B, C

9. LINES OF con FROM…TO

DATA: lt_source TYPE TABLE OF i,
lt_target TYPE TABLE OF i.
lt_source = VALUE #( ( 10 ) ( 20 ) ( 30 ) ( 40 ) ( 50 ) ).
lt_target = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
" Insertar solo filas 2-4 de source
INSERT LINES OF lt_source FROM 2 TO 4 INTO TABLE lt_target.
" Resultado: 1, 2, 3, 20, 30, 40

10. Insertar INITIAL LINE

DATA: lt_customers TYPE TABLE OF ty_customer.
lt_customers = VALUE #(
( id = 1 name = 'Müller' city = 'Berlin' )
).
" Insertar fila vacía en posición 1
INSERT INITIAL LINE INTO lt_customers INDEX 1.
" Resultado: (vacío), Müller
LOOP AT lt_customers INTO DATA(ls_cust).
WRITE: / ls_cust-id, ls_cust-name.
ENDLOOP.

11. INSERT con ASSIGNING

DATA: lt_customers TYPE TABLE OF ty_customer.
" Insertar fila y editarla directamente
INSERT VALUE #( id = 99 ) INTO TABLE lt_customers
ASSIGNING FIELD-SYMBOL(<ls_new>).
IF sy-subrc = 0.
<ls_new>-name = 'Recién creado'.
<ls_new>-city = 'Desconocido'.
ENDIF.

12. INSERT con REFERENCE INTO

DATA: lt_data TYPE TABLE OF ty_customer,
lr_line TYPE REF TO ty_customer.
INSERT VALUE #( id = 100 name = 'Test' ) INTO TABLE lt_data
REFERENCE INTO lr_line.
IF sy-subrc = 0.
lr_line->city = 'Actualización por referencia'.
ENDIF.

13. INSERT en LOOP (¡Precaución!)

" ¡ATENCIÓN: INSERT en LOOP puede causar bucles infinitos!
DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
" ¡INCORRECTO - Puede causar bucle infinito!
" LOOP AT lt_numbers INTO DATA(lv_num).
" IF lv_num = 2.
" INSERT 99 INTO lt_numbers INDEX sy-tabix.
" ENDIF.
" ENDLOOP.
" CORRECTO: Recopilar cambios e insertar después
DATA: lt_to_insert TYPE TABLE OF i.
LOOP AT lt_numbers INTO DATA(lv_num).
IF lv_num = 2.
APPEND 99 TO lt_to_insert.
ENDIF.
ENDLOOP.
INSERT LINES OF lt_to_insert INTO lt_numbers INDEX 2.

14. INSERT para diferentes tipos de tabla

Tipo de tablaINSERT … INDEXINSERT INTO TABLE
STANDARDSí (al final)
SORTEDNo (error de sintaxis)Sí (inserta ordenado)
HASHEDNo (error de sintaxis)Sí (por hash)
" STANDARD TABLE: Ambas variantes posibles
DATA: lt_standard TYPE STANDARD TABLE OF ty_customer.
INSERT ls_customer INTO lt_standard INDEX 1. " OK
INSERT ls_customer INTO TABLE lt_standard. " OK (al final)
" SORTED TABLE: Solo INTO TABLE
DATA: lt_sorted TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_sorted INDEX 1. " ¡ERROR DE SINTAXIS!
INSERT ls_customer INTO TABLE lt_sorted. " OK (inserta ordenado)
" HASHED TABLE: Solo INTO TABLE
DATA: lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_hashed INDEX 1. " ¡ERROR DE SINTAXIS!
INSERT ls_customer INTO TABLE lt_hashed. " OK

INSERT vs. APPEND

AspectoINSERTAPPEND
PosiciónCualquiera (INDEX) o por claveSiempre al final
SORTED TABLEINTO TABLE (inserta ordenado)Solo si se mantiene el orden
HASHED TABLEINTO TABLENo posible
Verificación de duplicadossy-subrc = 4 con UNIQUE KEYNinguna (excepto SORTED)
RendimientoCon INDEX: O(n)O(1)
" APPEND: Siempre al final
APPEND ls_customer TO lt_standard.
" INSERT INDEX: En posición específica
INSERT ls_customer INTO lt_standard INDEX 1.
" INSERT INTO TABLE: Según tipo de tabla
INSERT ls_customer INTO TABLE lt_sorted. " Inserta automáticamente ordenado

INSERT vs. MODIFY

" INSERT: Inserta nueva fila (error si hay duplicado)
INSERT ls_customer INTO TABLE lt_unique.
" MODIFY: Inserta O actualiza existente
MODIFY TABLE lt_unique FROM ls_customer.

Consejos de rendimiento

  1. Inserción masiva con LINES OF:

    " LENTO: INSERTs individuales
    LOOP AT lt_source INTO ls_line.
    INSERT ls_line INTO TABLE lt_target.
    ENDLOOP.
    " MÁS RÁPIDO: LINES OF
    INSERT LINES OF lt_source INTO TABLE lt_target.
  2. SORTED vs. STANDARD para inserciones frecuentes:

    " Para muchas inserciones: Recopilar en STANDARD TABLE, luego ordenar
    DATA: lt_collect TYPE STANDARD TABLE OF ty_data.
    LOOP AT lt_input INTO ls_input.
    APPEND ls_input TO lt_collect.
    ENDLOOP.
    SORT lt_collect BY key_field.
    DELETE ADJACENT DUPLICATES FROM lt_collect COMPARING key_field.
  3. INDEX-Insert desde atrás:

    " Para múltiples Index-Inserts: De atrás hacia adelante
    " para minimizar desplazamientos
    INSERT 'C' INTO lt_names INDEX 3.
    INSERT 'B' INTO lt_names INDEX 2.
    INSERT 'A' INTO lt_names INDEX 1.

Notas importantes / Mejores prácticas

  • INSERT ... INDEX solo posible para STANDARD TABLE.
  • INSERT INTO TABLE respeta la clave de tabla (ordena en SORTED, hashea en HASHED).
  • Con UNIQUE KEY: Verificar sy-subrc para detección de duplicados.
  • ¡Evitar INSERT en LOOP AT – peligro de bucles infinitos!
  • Usar LINES OF para inserciones masivas (más eficiente que inserciones individuales).
  • ASSIGNING y REFERENCE INTO permiten acceso directo a la fila insertada.
  • Para tablas de base de datos usar INSERT INTO dbtab.
  • APPEND es más rápido cuando la posición no importa (al final).
  • MODIFY combina INSERT y UPDATE en una sentencia.
  • Con SORTED TABLE se inserta automáticamente en la posición correcta.