Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Apprendre à programmer avec ABAP
  3. Les requêtes SQL
Extrait - Apprendre à programmer avec ABAP Les fondamentaux du développement sur SAP (avec exercices et corrigés)
Extraits du livre
Apprendre à programmer avec ABAP Les fondamentaux du développement sur SAP (avec exercices et corrigés) Revenir à la page d'achat du livre

Les requêtes SQL

Définition

La définition d’une table interne, faisant référence à un objet du dictionnaire de données (DDIC), a été développée, il reste maintenant à voir comment importer les données de la base de données et pour cela, SAP utilise le langage SQL.

Le SQL (signifiant Structured Query Language - requête de langage structurée en français) est tout simplement le langage de programmation permettant d’accéder et de gérer les données des bases de données (ajout, modification ou suppression). Pour SAP, il a été adapté en un ensemble d’opérations ABAP appelé OpenSQL. Pour schématiser, le traitement des données ressemblerait à ceci :

images/07RI01.png

Une application ABAP exécute une requête SQL. Il s’agit d’une opération permettant de traiter directement avec la base de données, comme par exemple la lecture d’une table, qui sera alors envoyée en OpenSQL à une interface. Celle-ci la traduira ensuite en Native SQL (langage SQL adapté pour les bases de données) afin de consulter la base, et d’importer les informations nécessaires. Elles seront enfin retournées via l’interface à l’application ABAP qui pourra poursuivre son traitement.

Comme vu dans le chapitre Dictionnaire de données...

SELECT


SELECT result  
       FROM source  
       [[FOR ALL ENTRIES IN itab] WHERE sql_cond  
       [GROUP BY group] [HAVING group_cond]  
       [ORDER BY sort_key]  
       INTO|APPENDING target   
       [UP TO n ROWS]  
       [BYPASSING BUFFER]  
       [CONNECTION con|(con_syntax).
 

Pour rappel, les instructions entre crochets sont optionnelles.

Tout d’abord le SELECT est l’instruction pour la lecture d’une table. Depuis la nouvelle version de SAP (pour rappel, de la version Ehp6 à Ehp7), prête pour l’interaction avec les bases de données HANA, beaucoup de fonctions sont apparues et il serait intéressant de s’y attarder.

Pour résumer, un SELECT a quatre paramètres et cette instruction pourrait se résumer à ceci :


SELECT col 
  FROM table 
  INTO dest 
  WHERE cond.
 

Sélection des colonnes col de la table table, à stocker dans dest, répondant aux conditions cond.

Ainsi cette section se divisera en quatre parties : le SELECT des colonnes avec ses options, le FROM, le INTO et le WHERE, puis une partie sur les options de l’instruction même.

1. SELECT

a. SINGLE [FOR UPDATE]

Cette option permet de sélectionner une seule ligne de la table déclarée dans le FROM. Bien entendu, le stockage défini dans le INTO ne peut être une table interne et sera nécessairement une structure ou une liste de variables.

Exemple


DATA s_driver_car TYPE zdriver_car. 
  
SELECT SINGLE * 
    FROM zdriver_car 
    INTO @s_driver_car.
 

L’option ’*’ signifie ’tous les champs’ et donc cette requête indique : sélectionner tous les champs du premier enregistrement de la table ZDRIVER_CAR et stocker dans la structure S_DRIVER_CAR.

Le symbole ’@’ défini comme escape character en anglais (se traduisant par caractère d’évasion) indique simplement que la variable, table interne ou structure fait partie des objets du programme et est donc externe à la base de données.

Résultat - structure S_DRIVER_CAR

MANDT

900

ID_DRIVER

C0001

SURNAME

DEBBACHE

NAME

AMINH

DATE_BIRTH

19781216

CITY

TOULOUSE

COUNTRY

FR

CAR_BRAND

PEUGEOT...

INSERT

Cette requête permet d’ajouter une ou plusieurs lignes à la table de la base de données soit via une structure, soit via une table interne, et de mettre à jour deux variables système :

  • SY-SUBRC pour indiquer l’état de l’opération :

  • 0 - la ou les lignes ont été correctement insérées.

  • 4 - une ou plusieurs erreurs se sont produites pendant le traitement.

  • SY-DBCNT retourne le nombre de lignes insérées

Via une structure


INSERT INTO dbtab VALUES struct.
 

Le système va tout d’abord vérifier que la clé primaire de l’enregistrement contenu dans la structure struct n’existe pas dans la table de base de données dbtab, pour ainsi l’insérer et retourner un code retour à 0. Si la clé primaire existe, l’enregistrement ne sera pas ajouté et le code retour sera égal à 4.

Exemple

Insérer un nouveau passager dans la table ZPASSENGER.


DATA: s_passager TYPE zpassenger. 
 
s_passager-id_passenger = 'P0005'. 
s_passager-surname      = 'THIERRY'. 
s_passager-name         = 'ROMAIN'. 
s_passager-date_birth   = '19930324'. 
s_passager-city         = 'MONTPELLIER'. ...

UPDATE

Ce type de requête permet de mettre à jour une ou plusieurs lignes de la table de la base de données de trois manières différentes, et mettra à jour deux variables système :

  • SY-SUBRC pour indiquer l’état de l’opération :

  • 0 - la ou les lignes ont été correctement mises à jour.

  • 4 - une ou plusieurs erreurs se sont produites pendant le traitement.

  • SY-DBCNT retourne le nombre de lignes mises à jour.

SET


UPDATE dbtab SET col1 = exp1, SET col2 = exp2,... [WHERE cond]...
 

Cette fonction signifie mettre à jour la table de la base de données dbtab, en appliquant la valeur définie par exp1 à la colonne col1, exp2 à col2...(SET) pour la condition cond définie (WHERE).

Les valeurs des champs sont modifiées directement dans la requête et même si la clause WHERE est optionnelle, elle est cependant bien recommandée au risque de modifier tous les enregistrements de la table.

Exemple

Pour le conducteur dont l’identifiant est ’C0003’, rajouter 5 euros pour tous les péages et 10 pour l’essence.


CONSTANTS: c_id_driver TYPE zdriver_id VALUE 'C0003'. 
 
UPDATE ztravel 
      SET toll  = toll  + 5, 
          gasol = gasol + 10 
      WHERE id_driver = @c_id_driver. 
 
  IF sy-subrc = 0. 
    WRITE 'Mise à jour réussie'. 
  ELSE. 
    WRITE 'Echec de la mise à jour'. 
  ENDIF.
 

La constante C_ID_DRIVER est créée avec le type ZDRIVER_ID et contient la valeur ’C0003’. Le programme procédera ensuite à la mise à jour de la table ZTRAVEL en ajoutant la valeur de 5 au champ TOLL, et 10 à celui de GASOL, pour tous les enregistrements dont le champ ID_DRIVER est égal à la constante C_ID_DRIVER. Si le code retour de la variable système est égal à 0, le programme affichera le texte ’Mise à jour réussie’, dans le cas contraire, il affichera...

MODIFY

Cette requête permet de modifier une ou plusieurs lignes de la table de base de données soit via une structure, soit via une table interne, et de mettre à jour deux variables système :

  • SY-SUBRC indique l’état de l’opération

  • SY-DBCNT retourne le nombre de lignes modifiées


MODIFY dbtab FROM struct.  
MODIFY dbtab FROM TABLE itab.
 

Elle se comporte de la même manière qu’un INSERT et un UPDATE : le système va vérifier si la ou les clé(s) primaire(s) définie(s) dans la structure struct ou la table interne itab existe(nt) dans la table de la base de données dbtab. Si celle-ci existe, alors la ligne sera modifiée (UPDATE), sinon elle sera créée (INSERT). Dans la majorité des cas, la variable système SY-SUBRC sera égale à 0.

DELETE

Cette requête permet de supprimer une ou plusieurs lignes de la table de base de données soit via une structure, soit via une table interne, et de mettre à jour deux variables système :

  • SY-SUBRC indique l’état de l’opération :

  • 0 - la ou les lignes ont été correctement mises à jour.

  • 4 - une ou plusieurs erreurs se sont produites pendant le traitement.

  • SY-DBCNT retourne le nombre de lignes supprimées


DELETE dbtab FROM struct.  
DELETE dbtab FROM TABLE itab.
 

La logique est la même que pour un INSERT ou un UPDATE : le système va vérifier si la (ou les) clé(s) primaire(s) définie(s) dans la structure struct ou la table interne itab existe(nt) dans la table de la base de données dbtab. Si celle-ci existe, alors la ligne sera supprimée, sinon elle sera mise de côté et retournera la variable de retour SY-SUBRC à 4.

Il existe également une autre manière de procéder à un DELETE avec la clause WHERE.


DELETE FROM dbtab WHERE. . .
 

Exemple

Supprimer le passager avec l’identifiant ’P0005’ dans la table ZPASSENGER.


CONSTANTS: c_user_id TYPE zpassenger_id VALUE 'P0005'. 
 
DELETE FROM zpassenger WHERE id_passenger = @c_user_id. 
 
IF sy-subrc = 0. 
  WRITE 'L''enregistrement a été supprimé avec succès'. ...

Index

Comme vu dans le chapitre Dictionnaire de données (DDIC), un index est une clé secondaire à une table de base de données, permettant d’améliorer considérablement les performances d’une sélection. Après avoir défini cette notion, il serait intéressant de voir comment l’utiliser dans une requête SQL.

Exemple

Sélection des enregistrements de la table ZTRAVEL mais avec un filtre sur les champs CITY_FROM et COUNTRY_FROM.


CONSTANTS: c_city_from TYPE ztravel-city_from VALUE 'TOULOUSE', 
           c_ctry_from TYPE ztravel-country_from VALUE 'FR'. 
 
SELECT city_from, 
       country_from, 
       city_to, 
       country_to, 
       date_travel, 
       hour_travel 
  FROM ztravel 
  INTO TABLE @DATA(t_travel) 
  WHERE city_from    = @c_city_from 
    AND country_from = @c_ctry_from.
 

Comme la sélection s’effectue sur des champs non clés de la table, il est possible, avec l’augmentation du nombre...

Exercice

 Créer un programme Z via la transaction SE38.

 En reprenant les données définies en début de chapitre, insérer les enregistrements suivants dans la table ZTRAVEL et donner un statut de succès ou d’échec de cette opération :

CHAMP

VALEUR_1

VALEUR_2

DATE_TRAVEL

13.02.2018

13.02.2018

HOUR_TRAVEL

08:00

15:30

ID_DRIVER

C0002

C0003

ID_PASSENGER1

P0003

P0001

ID_PASSENGER2

P0002

ID_PASSENGER3

P0004

CITY_FROM

LERIDA

PERPIGNAN

COUNTRY_FROM

ES

FR

CITY_TO

BARCELONE

MONTPELLIER

COUNTRY_TO

ES

FR

KMS

190

160

KMS_UNIT

KM

KM

DURATION

120

110

TOLL

11

18

GASOL

68

98

UNIT

EUR

EUR

 Une première sélection ira importer les enregistrements de la table ZTRAVEL et afficher pour chaque date de voyage les champs suivants :

  • Le nombre de voyages effectués

  • Le total des durées de voyage

  • Le total des distances parcourues

  • Le total des coûts de péage

  • Le total des coûts en carburant

  • Le total de tous les coûts journaliers

La table interne devra être déclarée dans un DATA après avoir défini son type TYPES.

 Le résultat sera affiché à l’écran avec un LOOP et l’instruction WRITE (mise en page libre).

 Une deuxième sélection importera une nouvelle fois les enregistrements de la table ZTRAVEL mais affichera les champs suivants :

  • Date de voyage

  • Heure de voyage

  • Nom et prénom...