Documentation PostgreSQL 8.0.2 | ||||
---|---|---|---|---|
Précédent | Arrière rapide | Chapitre 29. ECPG - SQL embarqué dans du C | Avance rapide | Suivant |
Dans la section Section 29.4, vous avez vu comment exécuter des instructions SQL à partir d'un programme SQL embarqué. Quelques-unes de ces instructions utilisent uniquement des valeurs fixes et ne proposent pas de possibilités d'insérer des valeurs fournies par l'utilisateur dans des instructions ou de traiter par le programme les valeurs renvoyées par la requête. Ces types d'instructions ne sont pas vraiment utiles dans les applications réelles. Cette section explique en détail comment passer des données entre votre programme C et les instructions SQL embarquées en utilisant un mécanisme simple appelé variables hôtes.
Passer des données entre le programme C et les instructions SQL est particulièrement simple en SQL embarqué. Plutôt que le programme ne copie les données dans l'instruction, ce qui implique diverses complications, telles que la bonne mise entre guillemets de la valeur, vous pouvez simplement écrire le nom de la variable C dans l'instruction SQL en la préfixant par un caractère deux-points. Par exemple:
EXEC SQL INSERT INTO unetable VALUES (:v1, 'foo', :v2);
Cette instruction fait référence à deux variables C nommées v1 et v2 et utilise aussi une chaîne littérale SQL pour illustrer que vous n'êtes pas restreint à utiliser un type de données ou un autre.
Ce style d'insertions de variables C dans des instructions SQL fonctionne dans tous les cas où une expression de valeur est attendue dans une instruction SQL. Dans l'environemment SQL, nous appelons les références à des variables C des variables hôtes.
Pour passer des données du programme à la base de données, par exemple comme paramètre d'une requête, ou pour passer des données de la base vers le programme, les variables C supposées contenir ces données doivent être déclarées dans des sections spécialement marquées pour que le préprocesseur du SQL embarqué soit averti de leur présence.
Cette section commence avec
EXEC SQL BEGIN DECLARE SECTION;
et se termine avec
EXEC SQL END DECLARE SECTION;
Entre ces lignes, il doit y avoir des déclarations normales de variables C, comme
int x; char foo[16], bar[16];
Vous pouvez avoir autant de sections de déclaration dans un programme que vous le souhaitez.
Les declarations sont aussi placées dans le fichier de sortie comme des variables C normales, du coup, il n'est plus besoin de les déclarer à nouveau. Les variables qui n'ont pas pour but d'être utilisées dans des commandes SQL peuvent être normalement déclarées en dehors des sections spéciales.
La définition d'une structure ou union doit aussi être saisie dans une section DECLARE. Sinon, le préprocesseur ne peut pas gérer ces types car il ne connaît pas leur définition.
Le type spécial VARCHAR est converti dans une struct nommée pour chaque variable. Une déclaration comme
VARCHAR var[180];
est convertie en
struct varchar_var { int len; char arr[180]; } var;
Cette structure est convenable pour interfacer des données SQL de type varchar.
Maintenant, vous devez être capable de passer des données générées par votre programme dans une commande SQL. Mais comment récupérer les résultats d'une requête ? Dans ce but, le SQL embarqué fournit des variantes spéciales des commandes habituelles SELECT et FETCH. Ces commandes ont une clause INTO spéciale qui sépcifient les variables hôtes dans lesquelles seront stockées les valeurs récupérées.
Voici un exemple :
/* * Soit la table suivante : * CREATE TABLE test1 (a int, b varchar(50)); */ EXEC SQL BEGIN DECLARE SECTION; int v1; VARCHAR v2; EXEC SQL END DECLARE SECTION; ... EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;
La clause INTO apparaît donc entre la liste select et la clause FROM. Les nombres d'éléments dans la liste select et celui de la liste après INTO (aussi appelée liste cible) doivent être identiques.
Voici un exemple utilisant la commande FETCH :
EXEC SQL BEGIN DECLARE SECTION; int v1; VARCHAR v2; EXEC SQL END DECLARE SECTION; ... EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test; ... do { ... EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2; ... } while (...);
Ici, la clause INTO apparaît après toutes les autres clauses.
Ces deux méthodes permettent seulement de récupérer une ligne à la fois. Si vous avez besoin de traiter des ensembles de résultats contenant potentiellement plus d'une ligne, vous devez utiliser un curseur, comme indiqué dans le second exemple.
Les exemples ci-dessus ne gèrent pas les valeurs nulles (NULL). En fait, les exemples de récupération afficheront une erreur si elles récupèrent une valeur nulle à partir de la base de données. Pour être capable de passer des valeurs nulles à la base de données ou de récupérer des valeurs nulles de la base de données, vous avez besoin d'ajouter une deuxième spécification de variable hôte pour chaque variable hôte contenant des données. Cette seconde variable est appelée l'indicateur et contient un drapeau indiquant si la valeur est nulle, auquel cas la valeur de la variable hôte réelle est ignorée. Voici un exemple qui gère correctement la récupération de valeurs nulles :
EXEC SQL BEGIN DECLARE SECTION; VARCHAR val; int val_ind; EXEC SQL END DECLARE SECTION: ... EXEC SQL SELECT b INTO :val :val_ind FROM test1;
La variable indicateur val_ind vaudra zéro si la valeur est non nulle et elle sera négative si la valeur est nulle.
L'indicateur a une autre fonction : si la valeur de l'indicateur est positive, cela signifie que la valeur est non nulle mais qu'elle a été tronquée lors de son stockage dans la variable hôte.
Précédent | Sommaire | Suivant |
Choisir une connexion | Niveau supérieur | SQL dynamique |