¿Se puede configurar / usar sp_executesql de forma predeterminada?

10

Estoy mirando una aplicación que usa consultas sql altamente dinámicas contra SQL Server. Mirando las consultas que se construyen de maneras muy extrañas y complicadas, pero esa es una historia diferente, le digo que brinde una buena razón para que no pueda (demasiado estúpido) descubrir las cosas por mí mismo ... No puedo ver cualquier código donde se envuelvan las consultas sp_executesql.

Pero cuando trazo, puedo ver muchas consultas envueltas sp_executesql. Toda la solución de la aplicación ni siquiera contiene el comando sp_executesql.

Entonces, me preguntaba si hay algún tipo de configuración que aún no conozca que obligue al software a ajustar las consultas con sp_executesql de forma predeterminada.

¿Qué podría causar este comportamiento?

Magier
fuente

Respuestas:

11

La razón por la que se envuelven las sentencias SQL sp_executesqles la configuración de la SqlCommand.Commandtypepropiedad y pasar los parámetros al comando.

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

El código anterior termina con este 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();

Este código termina con la ejecución del siguiente T-SQL:

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

Adición 23.12.15: Al usar un CommandType.Textcomando, los resultados son similares: tan pronto como se agrega un parámetro al objeto de comando, .NET ajustará toda la consulta sp_executesqly le pasará los parámetros.

Adición: después de profundizar más sp_executesql, la detección de parámetros y el almacenamiento en caché de planes de este comportamiento de las clases .NET tiene sentido para evitar una compilación de consultas frecuentes y una gran cantidad de planes. Por lo tanto, está diseñado básicamente para garantizar un mejor rendimiento de SQL Server en general, mientras que al mismo tiempo podría conducir a un bajo rendimiento de algunas consultas (problema de detección de parámetros) que se utilizan con valores de parámetros diferentes que el plan de consulta creado inicialmente.

Ver:

Los ejemplos anteriores se crearon con .NET Framework 4.5 y SQL Server 2008 Developer Edition.

Magier
fuente
5

Si se trata de una aplicación .NET, es muy probable que se deba a SqlCommand.ExecuteReader () . De acuerdo con la página principal de la clase SqlCommand , en la cuadrícula de descripciones de métodos en la sección "Comentarios", en ExecuteReader dice:

Ejecuta comandos que devuelven filas. Para aumentar el rendimiento, ExecuteReader invoca comandos utilizando el procedimiento almacenado del sistema Transact-SQL sp_executesql . Por lo tanto, ExecuteReader podría no tener el efecto que desea si se usa para ejecutar comandos como las instrucciones SET de Transact-SQL.

No tengo tiempo ahora para probar esto para confirmar su descripción, pero debería ser bastante fácil crear una aplicación de consola simple que realice una llamada muy simple, pasando algún texto de consulta e incluyendo un parámetro que se proporciona con un SqlParameter. Supongo que es así ExecuteNonQueryy ExecuteScalartambién lo uso, sp_executesqlya que también permiten pasar parámetros, entonces, ¿por qué habría una ruta diferente para cómo se ejecutan?

Solomon Rutzky
fuente