Partager via


Exécution préparée

L'API ODBC définit l'exécution préparée comme un moyen de réduire la charge d'analyse et de compilation associée à l'exécution répétée d'une instruction Transact-SQL. L'application génère une chaîne de caractères contenant une instruction SQL, puis l'exécute en deux étapes. Elle appelle SQLPrepare une fois afin que l'instruction soit analysée et compilée dans un plan d'exécution par le Moteur de base de données. Elle appelle ensuite SQLExecute pour chaque exécution du plan d'exécution préparée. Cela permet de réduire la charge d'analyse et de compilation pour chaque exécution. L'exécution préparée est couramment utilisée par les applications pour exécuter de manière répétée la même instruction SQL paramétrable.

Avec la plupart des bases de données, l'exécution préparée est plus rapide que l'exécution directe pour les instructions qui sont exécutées plus de trois ou quatre fois principalement du fait que l'instruction est compilée une seule fois, alors que 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 permettre de réduire le trafic réseau car le pilote peut envoyer un identificateur de plan d'exécution et les valeurs de paramètre, plutôt qu'une instruction SQL entière, à la source de données chaque fois que l'instruction est exécutée.

Les différences de performances entre l'exécution directe et l'exécution préparée sont moins importantes dans SQL Server 2000 et versions ultérieures du fait de la présence d'algorithmes améliorés qui permettent de détecter et de réutiliser des plans d'exécution de SQLExecDirect. Les avantages de l'exécution préparée en termes de performances s'étendent ainsi dans une certaine mesure aux instructions exécutées directement. Pour plus d'informations, consultez Exécution directe.

SQL Server 2000 et versions ultérieures proposent également la prise en charge native de l'exécution préparée. Un plan d'exécution est généré sur SQLPrepare, puis exécuté lorsque SQLExecute est appelé. Dans la mesure où SQL Server 2000 et versions ultérieures n'est pas requis pour générer des procédures stockées temporaires sur SQLPrepare, aucune charge mémoire supplémentaires n'est à noter sur les tables système dans tempdb.

Pour des raisons de performances, la préparation de l'instruction est différée jusqu'à ce que SQLExecute soit appelé ou qu'une opération de métapropriété (telle que SQLDescribeCol ou SQLDescribeParam dans ODBC) soit réalisée. Il s'agit du comportement par défaut. Toute erreur dans l'instruction en cours de préparée reste inconnue tant que l'instruction n'a pas été exécutée ou qu'une opération de métapropriété n'a pas été effectuée. La définition de l'attribut SQL_SOPT_SS_DEFER_PREPARE de l'instruction spécifique au pilote ODBC SQL Server Native Client sur SQL_DP_OFF peut désactiver ce comportement par défaut.

En cas de préparation différée, le fait d'appeler SQLDescribeCol ou SQLDescribeParam avant d'appeler SQLExecute génère un aller-retour supplémentaire sur le serveur. Sur SQLDescribeCol, le pilote supprime la clause WHERE de la requête et l'envoie au serveur avec SET FMTONLY ON pour obtenir la description des colonnes dans le premier jeu de résultats retourné par la requête. Sur SQLDescribeParam, le pilote appelle le serveur pour obtenir une description des expressions ou des colonnes référencées par tout marqueur de paramètre dans la requête. Cette méthode présente également certaines restrictions, comme le fait qu'elle ne permette pas de résoudre les paramètres dans les sous-requêtes.

L'utilisation excessive de SQLPrepare avec le pilote ODBC SQL Server Native Client a un impact négatif sur les performances, tout particulièrement en cas de connexion à des versions antérieures de SQL Server. L'exécution préparée ne doit pas être utilisée pour les instructions exécutées une seule fois. L'exécution préparée est plus lente que l'exécution directe en cas d'exécution unique d'une instruction car elle requiert un aller-retour réseau supplémentaire entre le client et le serveur. Sur les versions antérieures de SQL Server, elle génère également une procédure stockée temporaire.

Les instructions préparées ne peuvent pas être utilisées pour créer des objets temporaires sur SQL Server 2000 ou versions ultérieures, ou sur les versions antérieures de SQL Server si l'option permettant de générer des procédures stockées est active. Lorsque cette option est activée, l'instruction préparée est générée dans une procédure stockée temporaire qui est exécutée lorsque SQLExecute est appelé. Tout objet temporaire créé pendant l'exécution d'une procédure stockée est automatiquement supprimé lorsque la procédure se termine. Dans les deux exemples suivants, la table temporaire #sometable n'est pas créée si l'option permettant de générer des procédures stockées pour la préparation est active :

SQLPrepare(hstmt,
   "CREATE TABLE #sometable(cola int, colb char(8))",
   SQL_NTS);
SQLExecute(hstmt);

ou

SQLPrepare(hstmt,
   "SELECT * FROM Authors INTO #sometable",
   SQL_NTS);
SQLExecute(hstmt);

Certaines anciennes applications ODBC utilisaient SQLPrepare chaque fois que SQLBindParameter était utilisé. SQLBindParameter ne requiert pas l'utilisation de SQLPrepare et peut être utilisé avec SQLExecDirect. Par exemple, utilisez SQLExecDirect avec SQLBindParameter pour extraire le code de retour ou les paramètres de sortie d'une procédure stockée qui est exécutée une seule fois. N'utilisez pas SQLPrepare avec SQLBindParameter sauf si la même instruction sera exécutée plusieurs fois.

Voir aussi

Concepts