Dans de nombreux cas, les instructions SQL particulières qu'une application doit exécuter sont connues au moment de l'écriture de l'application. Néanmoins, dans certains cas, les instructions SQL sont composées à l'exécution ou fournies par une source externe. Dans ce cas, il n'est pas possible d'embarquer directement les instructions SQL dans le code source C, mais il existe une fonctionnalité permettant d'appeler des instructions SQL arbitraires fournies par l'intermédiaire d'une variable de type chaîne.
La façon la plus simple d'exécuter une instruction SQL arbitraire est d'utiliser la commande EXECUTE IMMEDIATE. Par exemple :
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "CREATE TABLE test1 (...);"; EXEC SQL END DECLARE SECTION; EXEC SQL EXECUTE IMMEDIATE :stmt;
Les instructions de ce type ne peuvent pas être utilisées pour récupérer des données (c'est-à-dire un SELECT).
Une façon plus puissante d'exécuter des instructions SQL arbitraires est de les préparer une seule fois et de les exécuter ensuite aussi souvent que nécessaire. Il est également possible de préparer une version généralisée d'une instruction, puis d'exécuter les versions spécifiques en substituant les paramètres. Lors de la préparation de l'instruction, il suffit d'écrire des points d'interrogation aux endroits où des paramètres seront substitués par la suite. Par exemple :
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "INSERT INTO test1 VALUES(?, ?);"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt USING 42, 'foobar';
Si l'instruction exécutée retourne des valeurs, il est nécessaire d'ajouter une clause INTO :
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?"; int v1, v2; VARCHAR v3; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37;
Une commande EXECUTE peut avoir une clause INTO, une clause USING, les deux ou aucune.
Lorsqu'une instruction préparée n'est plus utile, il est préférable de la désallouer :
EXEC SQL DEALLOCATE PREPARE name;