Exécution préparée dans ODBC

L’exécution préparée est un moyen efficace d’exécuter une instruction plusieurs fois. L’instruction est d’abord compilée ou préparée dans un plan d’accès. Le plan d’accès est ensuite exécuté une ou plusieurs fois ultérieurement. Pour plus d’informations sur les plans d’accès, consultez Traitement d’une instruction SQL.

L’exécution préparée est couramment utilisée par les applications verticales et personnalisées pour exécuter à plusieurs reprises la même instruction SQL paramétrable. Par exemple, le code suivant prépare une instruction pour mettre à jour les prix des différentes parties. Il exécute ensuite l’instruction plusieurs fois avec des valeurs de paramètre différentes à chaque fois.

SQLREAL       Price;  
SQLUINTEGER   PartID;  
SQLINTEGER    PartIDInd = 0, PriceInd = 0;  
  
// Prepare a statement to update salaries in the Employees table.  
SQLPrepare(hstmt, "UPDATE Parts SET Price = ? WHERE PartID = ?", SQL_NTS);  
  
// Bind Price to the parameter for the Price column and PartID to  
// the parameter for the PartID column.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 10, 0,  
                  &PartID, 0, &PartIDInd);  
  
// Repeatedly execute the statement.  
while (GetPrice(&PartID, &Price)) {  
   SQLExecute(hstmt);  
}  

L’exécution préparée est plus rapide que l’exécution directe pour les instructions exécutées plusieurs fois, principalement parce que l’instruction n’est compilée qu’une seule fois ; les instructions exécutées directement sont compilées chaque fois qu’elles sont exécutées. L’exécution préparée peut également fournir une réduction du trafic réseau, car le pilote peut envoyer un identificateur de plan d’accès à la source de données chaque fois que l’instruction est exécutée, plutôt qu’une instruction SQL entière, si la source de données prend en charge les identificateurs de plan d’accès.

L’application peut récupérer les métadonnées du jeu de résultats une fois l’instruction préparée et avant son exécution. Toutefois, le retour de métadonnées pour les instructions préparées, non exécutées est coûteux pour certains pilotes et doit être évité par des applications interopérables si possible. Pour plus d’informations, consultez Métadonnées du jeu de résultats.

L'exécution préparée ne doit pas être utilisée pour les instructions exécutées une seule fois. Pour ces instructions, il est légèrement plus lent que l’exécution directe, car elle nécessite un appel de fonction ODBC supplémentaire.

Important

La validation ou la restauration d’une transaction, soit en appelant explicitement SQLEndTran , soit en travaillant en mode de validation automatique, entraîne la suppression des plans d’accès pour toutes les instructions d’une connexion. Pour plus d’informations, consultez les options SQL_CURSOR_COMMIT_BEHAVIOR et SQL_CURSOR_ROLLBACK_BEHAVIOR dans la description de la fonction SQLGetInfo .

Pour préparer et exécuter une instruction, l’application :

  1. Appelle SQLPrepare et le transmet à une chaîne contenant l’instruction SQL.

  2. Définit les valeurs de tous les paramètres. Les paramètres peuvent être définis avant ou après la préparation de l’instruction. Pour plus d’informations, consultez Paramètres d’instruction, plus loin dans cette section.

  3. Appelle SQLExecute et effectue tout traitement supplémentaire nécessaire, comme l’extraction de données.

  4. Répète les étapes 2 et 3 si nécessaire.

  5. Lorsque SQLPrepare est appelé, le pilote :

    • Modifie l’instruction SQL pour utiliser la grammaire SQL de la source de données sans analyser l’instruction. Cela inclut le remplacement des séquences d’échappement décrites dans séquences d’échappement dans ODBC. L’application peut récupérer la forme modifiée d’une instruction SQL en appelant SQLNativeSql. Les séquences d’échappement ne sont pas remplacées si l’attribut d’instruction SQL_ATTR_NOSCAN est défini.

    • Envoie l’instruction à la source de données pour la préparation.

    • Stocke l’identificateur du plan d’accès retourné pour une exécution ultérieure (si la préparation a réussi) ou retourne des erreurs (si la préparation a échoué). Les erreurs incluent des erreurs syntaxiques telles que SQLSTATE 42000 (erreur de syntaxe ou violation d’accès) et des erreurs sémantiques telles que SQLSTATE 42S02 (table de base ou vue introuvable).

      Remarque

      Certains pilotes ne retournent pas d’erreurs à ce stade, mais retournent plutôt quand l’instruction est exécutée ou lorsque les fonctions de catalogue sont appelées. Par conséquent, SQLPrepare peut sembler avoir réussi lorsqu’il a échoué en fait.

  6. Quand SQLExecute est appelé, le pilote :

    • Récupère les valeurs de paramètre actuelles et les convertit si nécessaire. Pour plus d’informations, consultez Paramètres d’instruction, plus loin dans cette section.

    • Envoie l’identificateur du plan d’accès et les valeurs de paramètre converties à la source de données.

    • Retourne toutes les erreurs. Il s’agit généralement d’erreurs d’exécution telles que SQLSTATE 24000 (état du curseur non valide). Toutefois, certains pilotes retournent des erreurs syntaxiques et sémantiques à ce stade.

Si la source de données ne prend pas en charge la préparation des instructions, le pilote doit l’émuler dans la mesure du possible. Par exemple, le pilote peut ne rien faire lorsque SQLPrepare est appelé, puis exécuter l’exécution directe de l’instruction lorsque SQLExecute est appelé.

Si la source de données prend en charge la vérification de la syntaxe sans exécution, le pilote peut envoyer l’instruction pour vérifier quand SQLPrepare est appelé et envoyer l’instruction pour l’exécution lorsque SQLExecute est appelé.

Si le pilote ne peut pas émuler la préparation des instructions, il stocke l’instruction lorsque SQLPrepare est appelé et l’envoie pour l’exécution lorsque SQLExecute est appelé.

Étant donné que la préparation des instructions émulées n’est pas parfaite, SQLExecute peut retourner toutes les erreurs normalement retournées par SQLPrepare.