ABAP INSERT for Internal Tables: Inserting Rows

Category
ABAP-Statements
Published
Author
Johannes

The INSERT statement for internal tables inserts one or more rows at a specific position or according to the table key. Unlike APPEND, which always appends at the end, INSERT enables precise control over the insertion position.

Syntax

1. Insert Row by Index

INSERT <row> INTO <internal_table> INDEX <index>.

2. Insert Row According to Key

INSERT <row> INTO TABLE <internal_table>.

3. Insert Multiple Rows

INSERT LINES OF <source_table> INTO TABLE <target_table>.
INSERT LINES OF <source_table> FROM <from> TO <to> INTO <target_table> INDEX <index>.

4. Insert Initial Row

INSERT INITIAL LINE INTO <internal_table> INDEX <index>.
INSERT INITIAL LINE INTO TABLE <internal_table>.

System Fields

After INSERT:

  • sy-subrc:

    • 0: Row successfully inserted
    • 4: Row could not be inserted (e.g., duplicate with UNIQUE KEY)
  • sy-tabix: Index of the inserted row (with INDEX variant)

Examples

1. Insert Row by Index

DATA: lt_names TYPE TABLE OF string.
lt_names = VALUE #( ( `Anna` ) ( `Clara` ) ( `David` ) ).
" Insert Bernd at position 2
INSERT `Bernd` INTO lt_names INDEX 2.
" Result: Anna, Bernd, Clara, David
LOOP AT lt_names INTO DATA(lv_name).
WRITE: / sy-tabix, lv_name.
ENDLOOP.

2. Insert at Beginning

DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 2 ) ( 3 ) ( 4 ) ).
" Insert 1 at beginning
INSERT 1 INTO lt_numbers INDEX 1.
" Result: 1, 2, 3, 4

3. Insert Structure

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 = 'Miller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Insert new customer at position 2
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'Munich' ).
INSERT ls_customer INTO lt_customers INDEX 2.
" Result: Miller (1), Schmidt (2), Weber (3)

4. INSERT INTO TABLE (by Key)

DATA: lt_sorted TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_sorted = VALUE #(
( id = 1 name = 'Miller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Automatically inserted at correct position (sorted by key)
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'Munich' ).
INSERT ls_customer INTO TABLE lt_sorted.
IF sy-subrc = 0.
WRITE: / 'Successfully inserted at position:', sy-tabix.
ENDIF.
" Result: Automatically sorted between ID 1 and 3

5. Preventing Duplicates (UNIQUE KEY)

DATA: lt_unique TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_unique = VALUE #( ( id = 1 name = 'Miller' city = 'Berlin' ) ).
" Attempt to insert duplicate
ls_customer = VALUE #( id = 1 name = 'New' city = 'Cologne' ).
INSERT ls_customer INTO TABLE lt_unique.
IF sy-subrc = 4.
WRITE: / 'Duplicate! Row not inserted.'.
ENDIF.

6. HASHED TABLE

DATA: lt_hashed TYPE HASHED TABLE OF ty_customer
WITH UNIQUE KEY id.
" For HASHED TABLE: Always INSERT INTO TABLE (no INDEX!)
ls_customer = VALUE #( id = 5 name = 'Bauer' city = 'Dresden' ).
INSERT ls_customer INTO TABLE lt_hashed.
IF sy-subrc = 0.
WRITE: / 'Inserted into hash table.'.
ENDIF.

7. Insert Multiple Rows (LINES OF)

DATA: lt_source TYPE TABLE OF string,
lt_target TYPE TABLE OF string.
lt_source = VALUE #( ( `New1` ) ( `New2` ) ( `New3` ) ).
lt_target = VALUE #( ( `Old1` ) ( `Old2` ) ).
" Insert all rows from source into target (at end)
INSERT LINES OF lt_source INTO TABLE lt_target.
" Result: Old1, Old2, New1, New2, New3

8. LINES OF with 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` ) ).
" Insert rows at position 2
INSERT LINES OF lt_source INTO lt_target INDEX 2.
" Result: A, X, Y, Z, B, C

9. LINES OF with 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 ) ).
" Only insert rows 2-4 from source
INSERT LINES OF lt_source FROM 2 TO 4 INTO TABLE lt_target.
" Result: 1, 2, 3, 20, 30, 40

10. Insert INITIAL LINE

DATA: lt_customers TYPE TABLE OF ty_customer.
lt_customers = VALUE #(
( id = 1 name = 'Miller' city = 'Berlin' )
).
" Insert empty row at position 1
INSERT INITIAL LINE INTO lt_customers INDEX 1.
" Result: (empty), Miller
LOOP AT lt_customers INTO DATA(ls_cust).
WRITE: / ls_cust-id, ls_cust-name.
ENDLOOP.

11. INSERT with ASSIGNING

DATA: lt_customers TYPE TABLE OF ty_customer.
" Insert row and edit directly
INSERT VALUE #( id = 99 ) INTO TABLE lt_customers
ASSIGNING FIELD-SYMBOL(<ls_new>).
IF sy-subrc = 0.
<ls_new>-name = 'Newly created'.
<ls_new>-city = 'Unknown'.
ENDIF.

12. INSERT with 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 = 'Reference update'.
ENDIF.

13. INSERT in LOOP (Caution!)

" WARNING: INSERT in LOOP can cause infinite loops!
DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
" WRONG - Can cause infinite loop!
" LOOP AT lt_numbers INTO DATA(lv_num).
" IF lv_num = 2.
" INSERT 99 INTO lt_numbers INDEX sy-tabix.
" ENDIF.
" ENDLOOP.
" CORRECT: Collect changes and insert afterwards
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 for Different Table Types

Table TypeINSERT … INDEXINSERT INTO TABLE
STANDARDYesYes (at end)
SORTEDNo (syntax error)Yes (sorts in)
HASHEDNo (syntax error)Yes (by hash)
" STANDARD TABLE: Both variants possible
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 (at end)
" SORTED TABLE: Only INTO TABLE
DATA: lt_sorted TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_sorted INDEX 1. " SYNTAX ERROR!
INSERT ls_customer INTO TABLE lt_sorted. " OK (sorts in)
" HASHED TABLE: Only INTO TABLE
DATA: lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_hashed INDEX 1. " SYNTAX ERROR!
INSERT ls_customer INTO TABLE lt_hashed. " OK

INSERT vs. APPEND

AspectINSERTAPPEND
PositionArbitrary (INDEX) or by keyAlways at end
SORTED TABLEINTO TABLE (sorts in)Only if sorting preserved
HASHED TABLEINTO TABLENot possible
Duplicate checksy-subrc = 4 for UNIQUE KEYNone (except SORTED)
PerformanceWith INDEX: O(n)O(1)
" APPEND: Always at end
APPEND ls_customer TO lt_standard.
" INSERT INDEX: At specific position
INSERT ls_customer INTO lt_standard INDEX 1.
" INSERT INTO TABLE: According to table type
INSERT ls_customer INTO TABLE lt_sorted. " Automatically sorts in

INSERT vs. MODIFY

" INSERT: Inserts new row (error on duplicate)
INSERT ls_customer INTO TABLE lt_unique.
" MODIFY: Inserts OR updates existing
MODIFY TABLE lt_unique FROM ls_customer.

Performance Tips

  1. Mass insert with LINES OF:

    " SLOW: Individual INSERTs
    LOOP AT lt_source INTO ls_line.
    INSERT ls_line INTO TABLE lt_target.
    ENDLOOP.
    " FASTER: LINES OF
    INSERT LINES OF lt_source INTO TABLE lt_target.
  2. SORTED vs. STANDARD for frequent inserts:

    " For many inserts: STANDARD TABLE collect, then sort
    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 from back:

    " For multiple index inserts: From back to front
    " to minimize shifts
    INSERT 'C' INTO lt_names INDEX 3.
    INSERT 'B' INTO lt_names INDEX 2.
    INSERT 'A' INTO lt_names INDEX 1.

Important Notes / Best Practice

  • INSERT ... INDEX only possible for STANDARD TABLE.
  • INSERT INTO TABLE respects the table key (sorts for SORTED, hashes for HASHED).
  • For UNIQUE KEY: Check sy-subrc for duplicate detection.
  • Avoid INSERT in LOOP AT – danger of infinite loops!
  • Use LINES OF for mass inserts (more performant than individual inserts).
  • ASSIGNING and REFERENCE INTO enable direct access to the inserted row.
  • For database tables, use INSERT INTO dbtab.
  • APPEND is faster if position doesn’t matter (at end).
  • MODIFY combines INSERT and UPDATE in one statement.
  • For SORTED TABLE, rows are automatically inserted at the correct position.