ABAP INSERT, UPDATE, DELETE : Modifier les tables de base de donnees

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

Les instructions INSERT, UPDATE, DELETE et MODIFY sont les outils centraux en ABAP pour modifier les donnees dans les tables de base de donnees. Elles font partie d’Open SQL et permettent l’insertion, la mise a jour et la suppression d’enregistrements.

Important : Les modifications de la base de donnees ne sont sauvegardees de facon permanente qu’avec COMMIT WORK. Jusque-la, elles peuvent etre annulees avec ROLLBACK WORK.

INSERT - Inserer de nouveaux enregistrements

Syntaxe

" Inserer une seule ligne
INSERT INTO <table_bd> VALUES <zone_travail>.
" Inserer plusieurs lignes depuis une table interne
INSERT <table_bd> FROM TABLE <table_interne>
[ACCEPTING DUPLICATE KEYS].

Champs systeme

  • sy-subrc :

    • 0 : Insertion reussie.
    • 4 : La cle existe deja (doublon).
  • sy-dbcnt : Nombre de lignes inserees.

Exemples

Inserer une seule ligne

DATA: ls_customer TYPE zcustomer.
ls_customer-id = '1001'.
ls_customer-name = 'Muller GmbH'.
ls_customer-city = 'Berlin'.
ls_customer-created_at = sy-datum.
INSERT INTO zcustomer VALUES @ls_customer.
IF sy-subrc = 0.
WRITE: / 'Client cree avec succes.'.
ELSE.
WRITE: / 'Erreur : Le client existe deja.'.
ENDIF.

Inserer plusieurs lignes

DATA: lt_customers TYPE TABLE OF zcustomer.
lt_customers = VALUE #(
( id = '1002' name = 'Schmidt AG' city = 'Munich' )
( id = '1003' name = 'Weber KG' city = 'Hamburg' )
( id = '1004' name = 'Fischer GmbH' city = 'Cologne' )
).
INSERT zcustomer FROM TABLE @lt_customers.
WRITE: / 'Lignes inserees :', sy-dbcnt.

Avec ACCEPTING DUPLICATE KEYS

" Ignore les doublons, n'insere que les nouvelles lignes
INSERT zcustomer FROM TABLE @lt_customers
ACCEPTING DUPLICATE KEYS.
IF sy-subrc = 4.
WRITE: / 'Certaines lignes existaient deja.'.
ENDIF.
WRITE: / 'Inserees avec succes :', sy-dbcnt.

UPDATE - Modifier des enregistrements existants

Syntaxe

" Mettre a jour une ligne par cle (ligne complete)
UPDATE <table_bd> FROM <zone_travail>.
" Mettre a jour plusieurs lignes depuis une table interne
UPDATE <table_bd> FROM TABLE <table_interne>.
" Mettre a jour des champs specifiques avec SET
UPDATE <table_bd>
SET <champ1> = <valeur1>, <champ2> = <valeur2>, ...
WHERE <condition>.

Champs systeme

  • sy-subrc :

    • 0 : Au moins une ligne mise a jour.
    • 4 : Aucune ligne correspondante trouvee.
  • sy-dbcnt : Nombre de lignes mises a jour.

Exemples

Mettre a jour une seule ligne (ligne complete)

DATA: ls_customer TYPE zcustomer.
" D'abord lire
SELECT SINGLE * FROM zcustomer
WHERE id = '1001"
INTO @ls_customer.
IF sy-subrc = 0.
" Modifier
ls_customer-city = 'Francfort'.
ls_customer-updated_at = sy-datum.
" Reecrire
UPDATE zcustomer FROM @ls_customer.
IF sy-subrc = 0.
WRITE: / 'Client mis a jour.'.
ENDIF.
ENDIF.

Mettre a jour plusieurs lignes

DATA: lt_customers TYPE TABLE OF zcustomer.
" Charger et modifier les clients
SELECT * FROM zcustomer
WHERE city = 'Berlin"
INTO TABLE @lt_customers.
LOOP AT lt_customers ASSIGNING FIELD-SYMBOL(<fs_cust>).
<fs_cust>-region = 'Est'.
ENDLOOP.
" Reecrire toutes les lignes modifiees
UPDATE zcustomer FROM TABLE @lt_customers.
WRITE: / 'Lignes mises a jour :', sy-dbcnt.

Avec SET et WHERE (mise a jour en masse)

" Mettre tous les clients de Berlin sur Region 'Est"
UPDATE zcustomer
SET region = 'Est',
updated_at = @sy-datum
WHERE city = 'Berlin'.
WRITE: / 'Lignes mises a jour :', sy-dbcnt.

Calculer des valeurs avec SET

" Augmenter les prix de 10%
UPDATE zproduct
SET price = price * '1.1',
updated_at = @sy-datum
WHERE category = 'ELECTRONICS'.
" Incrementer un compteur
UPDATE zcounter
SET count = count + 1
WHERE id = 'VISITOR'.

DELETE - Supprimer des enregistrements

Syntaxe

" Supprimer une seule ligne par cle
DELETE <table_bd> FROM <zone_travail>.
" Supprimer plusieurs lignes depuis une table interne
DELETE <table_bd> FROM TABLE <table_interne>.
" Supprimer des lignes avec condition WHERE
DELETE FROM <table_bd> WHERE <condition>.

Champs systeme

  • sy-subrc :

    • 0 : Au moins une ligne supprimee.
    • 4 : Aucune ligne correspondante trouvee.
  • sy-dbcnt : Nombre de lignes supprimees.

Exemples

Supprimer une seule ligne

DATA: ls_customer TYPE zcustomer.
ls_customer-id = '1001'.
DELETE zcustomer FROM @ls_customer.
IF sy-subrc = 0.
WRITE: / 'Client supprime.'.
ELSE.
WRITE: / 'Client non trouve.'.
ENDIF.

Supprimer plusieurs lignes

DATA: lt_customers TYPE TABLE OF zcustomer.
" IDs des clients a supprimer
lt_customers = VALUE #(
( id = '1002' )
( id = '1003' )
).
DELETE zcustomer FROM TABLE @lt_customers.
WRITE: / 'Lignes supprimees :', sy-dbcnt.

Avec condition WHERE (suppression en masse)

" Supprimer tous les clients inactifs
DELETE FROM zcustomer
WHERE status = 'INACTIVE"
AND last_order_date < '20200101'.
WRITE: / 'Lignes supprimees :', sy-dbcnt.
" ATTENTION : Sans WHERE, toutes les lignes sont supprimees !
" DELETE FROM zcustomer. " Supprime toute la table !

MODIFY - Inserer ou mettre a jour (Upsert)

L’instruction MODIFY combine INSERT et UPDATE :

  • La cle existe -> La ligne est mise a jour
  • La cle n’existe pas -> La ligne est inseree

Syntaxe

" Une seule ligne
MODIFY <table_bd> FROM <zone_travail>.
" Plusieurs lignes
MODIFY <table_bd> FROM TABLE <table_interne>.

Champs systeme

  • sy-subrc : Toujours 0 (sauf erreurs de base de donnees).
  • sy-dbcnt : Nombre de lignes inserees/mises a jour.

Exemples

DATA: ls_config TYPE zconfig.
ls_config-key = 'MAX_USERS'.
ls_config-value = '100'.
ls_config-updated_at = sy-datum.
" Insere si inexistant ; met a jour si existant
MODIFY zconfig FROM @ls_config.
WRITE: / 'Configuration sauvegardee.'.
DATA: lt_products TYPE TABLE OF zproduct.
lt_products = VALUE #(
( id = 'P001' name = 'Laptop' price = 999 ) " Nouveau ou Update
( id = 'P002' name = 'Souris' price = 29 ) " Nouveau ou Update
( id = 'P003' name = 'Clavier' price = 79 ) " Nouveau ou Update
).
MODIFY zproduct FROM TABLE @lt_products.
WRITE: / 'Lignes traitees :', sy-dbcnt.

Comparaison des instructions

InstructionActionSi cle existanteSi nouvelle cle
INSERTInsererErreur (sy-subrc = 4)Insertion
UPDATEMettre a jourMise a jourErreur (sy-subrc = 4)
DELETESupprimerSuppressionErreur (sy-subrc = 4)
MODIFYUpsertMise a jourInsertion

Gestion des transactions

Les modifications de base de donnees ne sont pas sauvegardees immediatement. Elles sont d’abord dans un tampon de transaction :

" Effectuer les modifications
INSERT zcustomer FROM @ls_customer.
UPDATE zproduct SET price = 100 WHERE id = 'P001'.
DELETE FROM zlog WHERE created_at < '20240101'.
" Sauvegarder les modifications de facon permanente
COMMIT WORK.
" OU : Annuler les modifications
" ROLLBACK WORK.

Voir COMMIT WORK / ROLLBACK WORK pour les details sur la gestion des transactions.

Verrouillage (Locking)

Pour les acces paralleles, vous devriez utiliser les objets de verrouillage SAP :

" Poser un verrou
CALL FUNCTION 'ENQUEUE_EZCUSTOMER"
EXPORTING
id = ls_customer-id
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 0.
" Effectuer les modifications
UPDATE zcustomer FROM @ls_customer.
COMMIT WORK.
" Liberer le verrou
CALL FUNCTION 'DEQUEUE_EZCUSTOMER"
EXPORTING
id = ls_customer-id.
ELSE.
WRITE: / 'Enregistrement verrouille.'.
ENDIF.

Conseils de performance

  1. Preferer les operations en masse :

    " Mauvais : INSERTs individuels dans une boucle
    LOOP AT lt_customers INTO DATA(ls_cust).
    INSERT zcustomer FROM @ls_cust.
    ENDLOOP.
    " Mieux : Un INSERT pour toutes les lignes
    INSERT zcustomer FROM TABLE @lt_customers.
  2. UPDATE avec SET pour les modifications en masse :

    " Mauvais : Charger, modifier, reecrire
    SELECT * FROM zproduct INTO TABLE @DATA(lt_products).
    LOOP AT lt_products ASSIGNING FIELD-SYMBOL(<fs>).
    <fs>-status = 'ACTIVE'.
    ENDLOOP.
    UPDATE zproduct FROM TABLE @lt_products.
    " Mieux : UPDATE direct avec SET
    UPDATE zproduct SET status = 'ACTIVE' WHERE category = 'NEW'.
  3. ACCEPTING DUPLICATE KEYS avec INSERT : Si des doublons sont attendus, cela evite les erreurs et est plus efficace que de verifier au prealable.

  4. Frequence des COMMIT : N’executez pas COMMIT WORK apres chaque operation individuelle, mais apres des unites logiques.

Distinction : Tables de base de donnees vs. Tables internes

AspectTables de base de donneesTables internes
InstructionsINSERT, UPDATE, DELETE, MODIFYAPPEND, MODIFY, DELETE, INSERT
PersistancePermanente (apres COMMIT)Uniquement en memoire
SyntaxeINSERT <dbtab> FROM @waAPPEND wa TO itab
TransactionCOMMIT/ROLLBACKNon applicable

Remarques importantes / Bonnes pratiques

  • Verifiez toujours sy-subrc apres les operations de base de donnees.
  • Utilisez COMMIT WORK pour sauvegarder les modifications de facon permanente.
  • Posez des verrous pour les modifications critiques, afin d’eviter les conflits de donnees.
  • Preferez les operations en masse (FROM TABLE) aux boucles avec operations individuelles.
  • Soyez prudent avec DELETE sans WHERE - cela supprime toutes les lignes !
  • Utilisez MODIFY uniquement si vous avez vraiment besoin d’un comportement “upsert”.
  • Testez les operations critiques de base de donnees d’abord avec ROLLBACK WORK.
  • Utilisez SELECT pour lire et verifier les donnees avant modification.