Documentation PostgreSQL 14.22 » Interfaces client » ECPG -- SQL embarqué en C » Fonctionnement Interne

Précédent | Niveau supérieur | Suivant
36.16. Mode de compatibilité Oracle | Sommaire | Chapitre 37. Schéma d'information

## 36.17. Fonctionnement Interne

Cette section explique comment ECPG fonctionne en interne. Cette information peut être utile pour comprendre comment utiliser ECPG.

Les quatre premières lignes écrites sur la sortie par `ecpg` sont des lignes fixes. Deux sont des commentaires et deux sont des lignes d'inclusion nécessaires pour s'interfacer avec la librairie. Puis le préprocesseur lit le fichier et écrit la sortie. La plupart du temps, il répète simplement tout dans la sortie.

Quand il voit un ordre `EXEC SQL`, il intervient et le modifie. La commande débute par `EXEC SQL` et se termine par `;`. Tout ce qui se trouve entre deux est traité comme un ordre SQL et analysé pour substitution de variables.

Une substitution de variable se produit quand un symbole commence par un deux-points (`:`). La variable dont c'est le nom est recherchée parmi les variables qui ont été précédemment déclarées dans une section `EXEC SQL DECLARE`.

La fonction la plus importante de la librairie est `ECPGdo`, qui s'occupe de l'exécution de la plupart des commandes. Elle prend un nombre variable d'arguments. Le nombre de ces arguments peut rapidement dépasser la cinquantaine, et nous espérons que cela ne posera de problème sur aucune plateforme.

Les arguments sont:

Un numéro de ligne

  C'est le numéro de la ligne originale; c'est utilisé uniquement pour les messages d'erreu.

Une chaîne

  C'est la commande SQL à exécuter. Elle est modifiée par les variables d'entrée, c'est à dire les variables qui n'étaient pas connues au moment de la compilation mais qui doivent tout de même faire partie de la commande. Aux endroits où ces variables doivent être positionnées, la chaîne contient des `?`.

Variables d'Entrée

  Chaque variable d'entrée entraîne la création de dix arguments. (Voir plus bas.)

`ECPGt_EOIT`

  Un `enum` annonçant qu'il n'y a pas de variable d'entrées supplémentaires.

Variables de Sortie

  Chaque variable de sortie entraîne la création de dix arguments. (Voir plus bas.) Ces variables sont renseignées par la fonction.

`ECPGt_EORT`

  Un `enum` annonçant qu'il n'y a plus de variables.

Pour chaque variable qui fait partie d'une commande SQL, la fonction reçoit dix arguments:

1. Le type sous forme de symbole spécial.

2. Un pointeur vers la valeur ou un pointeur vers le pointeur.

3. La taille de la variable si elle est `char` ou `varchar`.

4. Le nombre d'éléments du tableau (pour les fetch sur tableau).

5. Le décalage vers le prochain élément du tableau (pour les fetch sur tableau).

6. Le type de la variable indicateur sous forme de symbole special.

7. Un pointeur vers la variable indicateur.

8. 0

9. Le nombre d'éléments du tableau d'indicateurs (pour les fetch sur tableau).

10. Le décalage vers le prochain élément du tableau d'indicateurs (pour les fetch sur tableau).

Notez que toutes les commandes SQL ne sont pas traitées de cette façon. Par exemple, un ordre d'ouverture de curseur comme:

    EXEC SQL OPEN cursor;

n'est pas copié vers la sortie. À la place, la commande de curseur `DECLARE` est utilisée à l'endroit de la commande `OPEN` parce qu'elle ouvre effectivement le curseur.

Voici un exemple complet expliquant la sortie du préprocesseur sur un fichier `foo.pgc` (quelques détails pourraient changer en fonction de la version exacte du préprocesseur):

    EXEC SQL BEGIN DECLARE SECTION;
    int index;
    int result;
    EXEC SQL END DECLARE SECTION;
    ...
    EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;

est traduit en :

    /* Processed by ecpg (2.6.0) */
    /* These two include files are added by the preprocessor */
    #include <ecpgtype.h>;
    #include <ecpglib.h>;

    /* exec sql begin declare section */

    #line 1 "foo.pgc"

     int index;
     int result;
    /* exec sql end declare section */
    ...
    ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ?     ",
            ECPGt_int,&(index),1L,1L,sizeof(int),
            ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
            ECPGt_int,&(result),1L,1L,sizeof(int),
            ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
    #line 147 "foo.pgc"

(L'indentation est ajoutée ici pour améliorer la lisibilité et n'est pas quelque chose que le préprocesseur effectue).