Hay una pregunta relacionada a este:

¿Cuál es el mejor método para pasar parámetros a SQLCommand?

Pero estoy deseando saber cuáles son las diferencias y si hay algún problema con las diferentes formas.

Yo normalmente uso una estructura algo como esto:

using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(SQL, conn))
{
     cmd.CommandType = CommandType.Text;
     cmd.CommandTimeout = Settings.Default.reportTimeout;
     cmd.Parameters.Add("type", SqlDbType.VarChar, 4).Value = type;

     cmd.Connection.Open();

     using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
     {
         adapter.Fill(ds);
     }
      //use data                    
}

Ahora hay varias maneras de agregar el cmd parámetros y me pregunto que es lo mejor:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
cmd.Parameters.Add("@Name").Value = "Bob";
cmd.Parameters.AddWithValue("@Name", "Bob");

Tener la longitud del campo en el paso de la varchars asumo que no es preferible, ya que es una magia valor que puede ser modificado posteriormente en la base de datos. Es esto correcto? No se produce ningún problema de pasar un varchar de esta manera (de rendimiento o de otro tipo), supongo que por defecto es de tipo varchar(max) o la base de datos equivalente. Estoy razonablemente contentos con este trabajo.

La parte que me preocupa más es la pérdida de la SqlDbType enum si estoy usando la tercera o cuarta de las opciones que se enumeran más arriba yo no soy el suministro de un tipo en absoluto. Hay casos en los que esto no funciona me imagino problemas con varchar incorrecta del elenco char o viceversa, o tal vez problemas con decimales para el dinero….

En términos de la base de datos el tipo de campo que yo diría que es mucho menos probable el cambio de la longitud por lo que es digno de la retención?

  • Mientras no responder a su pregunta, usted sabe que Usted no necesita para abrir la conexión antes de llamar a la SqlDataAdapter.Fill(), y que no hay beneficio en no hacerlo?
  • buen punto. Yo sabía que a pesar de que ha sido un descuido en mi código. Creo que me tomé el original del bloque de código en algún lugar que yo estaba usando un SqlDataReader no un adaptador (no necesita abrir la conexión para que el derecho?). Que es lo que se obtiene malo para copiar/pegar de programación :-). Fijo en mi código.
  • sólo pensé que mencionar, como uno de esos «oscuros consejos que la gente puede no saber acerca de»
InformationsquelleAutor PeteT | 2011-01-07

2 Comentarios

  1. 56

    En mi experiencia, me gustaría asegurarse de que hago estas cosas:

    • asegúrese de que es lo que define la tipo de datos para el parámetro. ADO.NET hace un trabajo decente a adivinar, pero en algunos casos, puede ser terriblemente fuera así me gustaría evitar este método:

      cmd.Parameters.Add("@Name").Value = "Bob";
      cmd.Parameters.AddWithValue("@Name", "Bob");

      Dejar ADO.NET supongo que el tipo del parámetro por el valor pasado es difícil, y si por alguna razón, esos son realmente difíciles errores para rastrear y encontrar! Imagínese lo que sucede cuando se pasa de un DBNull.Value – ¿qué tipo de datos debe ADO.NET pick para que?

      Acaba de ser explícito – decir de qué tipo es lo que se desea!

    • si usted está utilizando los parámetros de la cadena, asegúrese de definir explícitamente la longitud – así que me gustaría evitar este método, también:

      cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";

      Si usted no proporciona una longitud, ADO.NET podría defecto a algún valor arbitrario, o la longitud de la cadena que se pasa como un valor, o algo más – nunca estás seguro. Y si su longitud no coincide con lo que el procedimiento almacenado realmente espera, usted puede ver la conversión y otras sorpresas desagradables. Así, si se define una cadena, definir su longitud, también!

    Así que, en su caso, el único enfoque que realmente funciona para mí es este de aquí:

    cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

    porque a) se define el tipo de datos a utilizar de forma explícita, y b) se define la longitud de la cadena explícitamente.

    • Si estás utilizando un procedimiento almacenado, no puede obtener el tipo de parámetro a partir de la meta-datos proporcionados por SqlCommandBuilder.DeriveParameters(cmd)?
    • Si la Longitud pasa de ser el de la subyacente definición de los parámetros? Y si es así, no se que tipo de violar SECO?
  2. 6

    Agregando el tipo, sus peticiones son más propensos a mejorar el rendimiento mediante el uso de la caché del plan de consulta.

    He aquí una cita de MSDN:

    Comandos con parámetros también puede mejorar la ejecución de la consulta de rendimiento, debido a que ayudan a la base de datos del servidor de coincidir la entrantes comando, con un adecuado caché del plan de consulta.

    Más para leer en La ejecución del Plan de almacenamiento en Caché y la Reutilización.

    • Todos los de Pete opciones son paramterised, así que me sorprendería si la adición de los parámetros en las diferentes maneras en que afecta el rendimiento — ciertamente no se menciona explícitamente en el artículo que has enlazado.
    • Yo de acuerdo. Lo que el artículo que describe es que al definir el parámetro tan exactos como sea posible, su más probable es que la memoria caché del plan de consulta que será utilizado y, a continuación, con un mayor rendimiento. La sub sección Parametrización Simple, dice esto: En SQL Server, utilizando parámetros o marcadores de parámetros en las instrucciones Transact-SQL que aumenta la capacidad del motor relacional para que coincida con las nuevas instrucciones SQL existente, previamente compilado de los planes de ejecución.

Dejar respuesta

Please enter your comment!
Please enter your name here