Sp_executesql peut-il être configuré / utilisé par défaut?


10

Je regarde une application qui utilise des requêtes SQL hautement dynamiques contre SQL Server. En regardant les requêtes qui sont construites de manière très étrange et compliquée, mais c'est une autre histoire, je le dis pour donner une bonne raison pour que je ne puisse pas (trop stupide) trouver les choses moi-même ... Je ne peux pas voir tout code contenant les requêtes sp_executesql.

Mais quand je trace, je peux voir beaucoup de requêtes arriver avec sp_executesql. L'ensemble de la solution d'application ne contient même pas du tout la commande sp_executesql.

Je me suis donc demandé s'il existe une sorte de configuration que je ne connais pas encore qui oblige le logiciel à encapsuler les requêtes avec sp_executesql par défaut?

Qu'est-ce qui pourrait provoquer ce comportement?

Réponses:


11

La raison pour laquelle les instructions SQL sont encapsulées sp_executesqlest le réglage de la SqlCommand.Commandtypepropriété et la transmission des paramètres à la commande.

SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.StoredProcedure;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Le code ci-dessus se termine par ce T-SQL:

exec proc1 @param1=1
SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.Text;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Ce code se termine par l'exécution du T-SQL suivant:

exec sp_executesql N'proc1',N'@param1 int',@param1=1

Ajout 23.12.15: En utilisant une CommandType.Textcommande, les résultats sont similaires: dès qu'un paramètre est ajouté à l'objet de commande, .NET encapsule la requête entière sp_executesqlet lui passe les paramètres.

Addition: Après avoir approfondi sp_executesql, le reniflage des paramètres et la mise en cache du plan, ce comportement des classes .NET est totalement logique afin d'éviter la compilation de requêtes fréquentes et le nombre de plans. Il est donc essentiellement conçu pour garantir de meilleures performances SQL Server en général, tout en entraînant des performances médiocres pour certaines requêtes (problème de détection de paramètres) utilisées avec des valeurs de paramètres différentes de celles du plan de requête créé initialement.

Voir:

L'exemple ci-dessus a été créé à l'aide de .NET Framework 4.5 et de SQL Server 2008 Developer Edition.


5

S'il s'agit d'une application .NET, il s'agit très probablement d'un résultat de l' appel de SqlCommand.ExecuteReader () . Selon la page principale de la classe SqlCommand , dans la grille des descriptions de méthodes de la section "Remarques", sous ExecuteReader, il est indiqué:

Exécute des commandes qui renvoient des lignes. Pour des performances accrues, ExecuteReader appelle des commandes à l'aide de la procédure stockée système Transact-SQL sp_executesql . Par conséquent, ExecuteReader peut ne pas avoir l'effet souhaité s'il est utilisé pour exécuter des commandes telles que les instructions Transact-SQL SET.

Je n'ai pas le temps maintenant de tester cela pour confirmer leur description, mais il devrait être assez facile de créer une application console simple qui effectue un appel très simple, en transmettant du texte de requête et en incluant un paramètre fourni avec un SqlParameter. Je pense que ExecuteNonQueryet ExecuteScalarutiliser aussi sp_executesqlcar ils permettent également de passer des paramètres, alors pourquoi y aurait - il un chemin différent de la façon dont ceux -ci sont exécutés?

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.