ABAP INSERT pour tables internes : Inserer des lignes

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

L’instruction INSERT pour les tables internes insere une ou plusieurs lignes a une position specifique ou selon la cle de table. Contrairement a APPEND, qui ajoute toujours a la fin, INSERT permet un controle precis sur la position d’insertion.

Syntaxe

1. Inserer une ligne par index

INSERT <ligne> INTO <table_interne> INDEX <index>.

2. Inserer une ligne selon la cle

INSERT <ligne> INTO TABLE <table_interne>.

3. Inserer plusieurs lignes

INSERT LINES OF <table_source> INTO TABLE <table_cible>.
INSERT LINES OF <table_source> FROM <de> TO <a> INTO <table_cible> INDEX <index>.

4. Inserer une ligne initiale

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

Champs systeme

Apres INSERT :

  • sy-subrc :

    • 0 : Ligne inseree avec succes
    • 4 : Ligne non inseree (ex. doublon avec UNIQUE KEY)
  • sy-tabix : Index de la ligne inseree (variante INDEX)

Exemples

1. Inserer une ligne par index

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

2. Inserer au debut

DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 2 ) ( 3 ) ( 4 ) ).
" Inserer 1 au debut
INSERT 1 INTO lt_numbers INDEX 1.
" Resultat : 1, 2, 3, 4

3. Inserer une 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 = 'Muller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Inserer un nouveau client a la position 2
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'Munich' ).
INSERT ls_customer INTO lt_customers INDEX 2.
" Resultat : Muller (1), Schmidt (2), Weber (3)

4. INSERT INTO TABLE (selon la cle)

DATA: lt_sorted TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_sorted = VALUE #(
( id = 1 name = 'Muller' city = 'Berlin' )
( id = 3 name = 'Weber' city = 'Hamburg' )
).
" Insere automatiquement a la bonne position (trie par cle)
ls_customer = VALUE #( id = 2 name = 'Schmidt' city = 'Munich' ).
INSERT ls_customer INTO TABLE lt_sorted.
IF sy-subrc = 0.
WRITE: / 'Insere avec succes a la position :', sy-tabix.
ENDIF.
" Resultat : Automatiquement trie entre ID 1 et 3

5. Empecher les doublons (UNIQUE KEY)

DATA: lt_unique TYPE SORTED TABLE OF ty_customer
WITH UNIQUE KEY id.
lt_unique = VALUE #( ( id = 1 name = 'Muller' city = 'Berlin' ) ).
" Tentative d'inserer un doublon
ls_customer = VALUE #( id = 1 name = 'Nouveau' city = 'Cologne' ).
INSERT ls_customer INTO TABLE lt_unique.
IF sy-subrc = 4.
WRITE: / 'Doublon ! Ligne non inseree.'.
ENDIF.

6. HASHED TABLE

DATA: lt_hashed TYPE HASHED TABLE OF ty_customer
WITH UNIQUE KEY id.
" Pour HASHED TABLE : Toujours INSERT INTO TABLE (pas d'INDEX !)
ls_customer = VALUE #( id = 5 name = 'Bauer' city = 'Dresden' ).
INSERT ls_customer INTO TABLE lt_hashed.
IF sy-subrc = 0.
WRITE: / 'Insere dans la table de hachage.'.
ENDIF.

7. Inserer plusieurs lignes (LINES OF)

DATA: lt_source TYPE TABLE OF string,
lt_target TYPE TABLE OF string.
lt_source = VALUE #( ( `Nouveau1` ) ( `Nouveau2` ) ( `Nouveau3` ) ).
lt_target = VALUE #( ( `Ancien1` ) ( `Ancien2` ) ).
" Inserer toutes les lignes de source dans target (a la fin)
INSERT LINES OF lt_source INTO TABLE lt_target.
" Resultat : Ancien1, Ancien2, Nouveau1, Nouveau2, Nouveau3

8. LINES OF avec 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` ) ).
" Inserer les lignes a la position 2
INSERT LINES OF lt_source INTO lt_target INDEX 2.
" Resultat : A, X, Y, Z, B, C

9. LINES OF avec 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 ) ).
" Inserer uniquement les lignes 2-4 de source
INSERT LINES OF lt_source FROM 2 TO 4 INTO TABLE lt_target.
" Resultat : 1, 2, 3, 20, 30, 40

10. Inserer une INITIAL LINE

DATA: lt_customers TYPE TABLE OF ty_customer.
lt_customers = VALUE #(
( id = 1 name = 'Muller' city = 'Berlin' )
).
" Inserer une ligne vide a la position 1
INSERT INITIAL LINE INTO lt_customers INDEX 1.
" Resultat : (vide), Muller
LOOP AT lt_customers INTO DATA(ls_cust).
WRITE: / ls_cust-id, ls_cust-name.
ENDLOOP.

11. INSERT avec ASSIGNING

DATA: lt_customers TYPE TABLE OF ty_customer.
" Inserer une ligne et l'editer directement
INSERT VALUE #( id = 99 ) INTO TABLE lt_customers
ASSIGNING FIELD-SYMBOL(<ls_new>).
IF sy-subrc = 0.
<ls_new>-name = 'Nouvellement cree'.
<ls_new>-city = 'Inconnu'.
ENDIF.

12. INSERT avec 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 = 'Mise a jour par reference'.
ENDIF.

13. INSERT dans LOOP (Attention !)

" ATTENTION : INSERT dans LOOP peut causer des boucles infinies !
DATA: lt_numbers TYPE TABLE OF i.
lt_numbers = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
" FAUX - Peut causer une boucle infinie !
" LOOP AT lt_numbers INTO DATA(lv_num).
" IF lv_num = 2.
" INSERT 99 INTO lt_numbers INDEX sy-tabix.
" ENDIF.
" ENDLOOP.
" CORRECT : Collecter les modifications et inserer apres
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 pour differents types de table

Type de tableINSERT … INDEXINSERT INTO TABLE
STANDARDOuiOui (a la fin)
SORTEDNon (erreur syntaxe)Oui (tri automatique)
HASHEDNon (erreur syntaxe)Oui (par hash)
" STANDARD TABLE : Les deux variantes possibles
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 (a la fin)
" SORTED TABLE : Uniquement INTO TABLE
DATA: lt_sorted TYPE SORTED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_sorted INDEX 1. " ERREUR SYNTAXE !
INSERT ls_customer INTO TABLE lt_sorted. " OK (tri automatique)
" HASHED TABLE : Uniquement INTO TABLE
DATA: lt_hashed TYPE HASHED TABLE OF ty_customer WITH UNIQUE KEY id.
" INSERT ls INTO lt_hashed INDEX 1. " ERREUR SYNTAXE !
INSERT ls_customer INTO TABLE lt_hashed. " OK

INSERT vs. APPEND

AspectINSERTAPPEND
PositionQuelconque (INDEX) ou selon cleToujours a la fin
SORTED TABLEINTO TABLE (tri automatique)Seulement si tri preserve
HASHED TABLEINTO TABLENon possible
Detection doublonsy-subrc = 4 avec UNIQUE KEYAucune (sauf SORTED)
PerformanceAvec INDEX : O(n)O(1)
" APPEND : Toujours a la fin
APPEND ls_customer TO lt_standard.
" INSERT INDEX : A une position specifique
INSERT ls_customer INTO lt_standard INDEX 1.
" INSERT INTO TABLE : Selon le type de table
INSERT ls_customer INTO TABLE lt_sorted. " Tri automatique

INSERT vs. MODIFY

" INSERT : Insere une nouvelle ligne (erreur si doublon)
INSERT ls_customer INTO TABLE lt_unique.
" MODIFY : Insere OU met a jour l'existant
MODIFY TABLE lt_unique FROM ls_customer.

Conseils de performance

  1. Insertion en masse avec LINES OF :

    " LENT : INSERTs individuels
    LOOP AT lt_source INTO ls_line.
    INSERT ls_line INTO TABLE lt_target.
    ENDLOOP.
    " PLUS RAPIDE : LINES OF
    INSERT LINES OF lt_source INTO TABLE lt_target.
  2. SORTED vs. STANDARD pour insertions frequentes :

    " Pour beaucoup d'insertions : Collecter dans STANDARD TABLE, puis trier
    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 depuis la fin :

    " Pour plusieurs Index-Inserts : De la fin vers le debut
    " pour minimiser les decalages
    INSERT 'C' INTO lt_names INDEX 3.
    INSERT 'B' INTO lt_names INDEX 2.
    INSERT 'A' INTO lt_names INDEX 1.

Remarques importantes / Bonnes pratiques

  • INSERT ... INDEX uniquement pour STANDARD TABLE.
  • INSERT INTO TABLE respecte la cle de table (tri pour SORTED, hash pour HASHED).
  • Avec UNIQUE KEY : Verifiez sy-subrc pour la detection de doublons.
  • Evitez INSERT dans LOOP AT - Risque de boucles infinies !
  • Utilisez LINES OF pour les insertions en masse (plus performant que les inserts individuels).
  • ASSIGNING et REFERENCE INTO permettent un acces direct a la ligne inseree.
  • Pour les tables de base de donnees, utilisez INSERT INTO dbtab.
  • APPEND est plus rapide si la position n’a pas d’importance (a la fin).
  • MODIFY combine INSERT et UPDATE en une seule instruction.
  • Avec SORTED TABLE, l’insertion se fait automatiquement a la position correcte.