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

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

o

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

o

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

Parece que el primero podría ser de alguna manera «mejor», ya sea en cuanto al rendimiento o de comprobación de error sabio. Pero me gustaría saber más definitivamente.

InformationsquelleAutor TAG | 2008-11-16

5 Comentarios

  1. 53

    También puede utilizar AddWithValue(), pero hay que ser conscientes de la posibilidad de que el mal implícito de conversión de tipo.

    cmd.Parameters.AddWithValue("@Name", "Bob");
    • puede haber algunos problemas utilizando AddWithValue()
    • Esta es otra forma, pero la pregunta es la mejor manera, no esta uno seguro.
    • … «pero hay que ser conscientes de la posibilidad de que el mal implícito el tipo de conversión». Entonces, ¿cómo es este el mejor método y el aceptado la respuesta?!
  2. 61

    Lo que está pasando allí?

    De citar las listas de parámetros para varias sobrecargas de Add. Estos son los métodos prácticos que corresponden directamente a sobrecargas del constructor para el SqlParameter clase. Ellos esencialmente construir el objeto de parámetro utilizando el constructor de la misma firma como la conveniencia del método de llamada y, a continuación, llamar a SqlParameterCollection.Add(SqlParameter) como este:

    SqlParameter foo = new SqlParameter(parameterName, dbType, size);
    this.Add(foo);

    AddWithValue es similar, pero lleva la comodidad incluso más lejos, y también establecer el valor. Sin embargo, en realidad, fue introducido para resolver un marco de falla. Para citar a MSDN,

    La sobrecarga de Add que toma un
    cadena y un objeto en desuso
    debido a la posible ambigüedad con la
    SqlParameterCollection.Add sobrecarga
    que toma un String y un SqlDbType
    valor de enumeración donde pasar una
    entero con la cadena podría ser
    interpretado como siendo la
    el valor del parámetro o el correspondiente
    SqlDbType valor. Uso AddWithValue
    cada vez que desee agregar un parámetro
    especificando su nombre y valor.

    Las sobrecargas del constructor para el SqlParameter clase son meras conveniencias para la configuración de las propiedades de la instancia. Que acortar el código, con un impacto marginal en el rendimiento: el constructor puede omitir métodos setter y operar directamente sobre los miembros privados. Si hay una diferencia que no será mucho.

    ¿Qué debo hacer?

    Nota siguiente (de MSDN)

    Bidireccional y de salida
    los parámetros y valores de retorno, que
    debe establecer el valor de Size. Este es
    no se requiere para los parámetros de entrada, y
    si no se establece explícitamente, el valor es
    inferido a partir de que el tamaño real de la
    parámetro especificado cuando un
    con parámetros de ejecutar la sentencia.

    El tipo por defecto es de entrada. Sin embargo, si se permite que el tamaño de la que se desprende como este y reciclar el objeto de parámetro en un bucle (que dijeron que estaban preocupados por el rendimiento), a continuación, el tamaño será determinado por el primer valor y el posterior valores que no será cortada. Obviamente esto es significativo sólo para la variable longitud de valores como cadenas de caracteres.

    Si usted está pasando la misma lógica parámetro repetidamente en un bucle te recomiendo crear un objeto SqlParameter fuera del bucle y de tamaño adecuado. La sobre-dimensionamiento de un tipo de datos varchar es inofensivo, lo que si es un pan de PITA para obtener el exacto máximo, acaba de establecer que es más grande de lo que usted espera de la columna. Porque eres el reciclaje de los objetos en lugar de crear uno nuevo para cada iteración, el consumo de memoria a través de la duración del bucle es probable que gota incluso si usted consigue un poco emocionado con el sobredimensionamiento.

    La verdad sea dicha, a menos que el proceso de miles de llamadas, nada de esto va a hacer mucha diferencia. AddWithValue crea un nuevo objeto, dejando de lado el tamaño del problema. Es corto y dulce y fácil de entender. Si el bucle a través de miles, el uso de mi enfoque. Si no, utilice AddWithValue para mantener el código simple y fácil de mantener.


    2008 fue hace mucho tiempo

    En los años desde que escribí esto, el mundo ha cambiado. Hay un nuevo tipo de fecha, y también hay un problema que no ha cruzado mi mente hasta que un reciente problema con las fechas, me hizo pensar acerca de las implicaciones de la ampliación.

    Ensanchamiento y estrechamiento, para aquellos no familiarizados con los términos, son las cualidades de conversiones de tipos de datos. Si asigna un int a un doble, no hay ninguna pérdida de precisión doble porque es «más amplio». Siempre es seguro hacer esto, así que la conversión es automática. Esta es la razón por la que puede asignar un int a un doble pero ir por el otro camino, usted tiene que hacer una conversión explícita – doble de tipo int, es un estrechamiento de la conversión de la posible pérdida de precisión.

    Esto se puede aplicar a las cadenas: NVARCHAR es más amplia que la de tipo VARCHAR, así que usted puede asignar un tipo de datos VARCHAR a un tipo NVARCHAR pero va para otro lado requiere una conversión. Comparación de las obras, porque el tipo de datos VARCHAR implícitamente se amplía a NVARCHAR, pero esto va a interferir con el uso de los índices!

    C# son las cadenas de caracteres Unicode, por lo que AddWithValue producirá un parámetro de tipo NVARCHAR. En el otro extremo, los valores de la columna de tipo VARCHAR ampliar a NVARCHAR para la comparación. Esto no detiene la ejecución de la consulta pero impide que los índices de la que se utiliza. Esto es malo.

    ¿Qué se puede hacer acerca de esto? Usted tiene dos posibles soluciones.

    • Explícitamente el tipo del parámetro. Esto significa no más de AddWithValue
    • Cambiar toda la columna de cadena de tipo NVARCHAR.

    De amaraje forzoso VARCHAR es probablemente la mejor idea. Es un simple cambio con consecuencias predecibles y mejora la localización de la historia. Sin embargo, usted no puede tener esto como una opción.

    Estos días no hago un montón de directo ADO.NET. Linq2Sql ahora es mi arma de elección, y el acto de escribir esta actualización me ha dejado preguntando cómo se ocupa de este problema. Tengo un repentino deseo ardiente de revisar mi código de acceso a datos para la búsqueda a través de las columnas VARCHAR.


    2019 y el mundo se ha movido en de nuevo

    Linq2Sql no está disponible en dotnet Core, así que me encuentro con Dapper. La [N]VARCHAR problema es todavía una cosa, pero ya no está tan lejos enterrado. Creo que también se puede utilizar ADO para que las cosas han llegado en un círculo completo en ese sentido.

    • «Tengo un repentino deseo ardiente de purgar mis bases de datos de tipo VARCHAR» – y el doble de espacio de almacenamiento requerido, y aumentar la memoria necesaria para ejecutar las consultas. Incluso más de un problema ahora con alojado DB. Yo uso NVARCHAR donde el Dominio requiere.
    • el doble de la de almacenamiento…» sí, es así? El precio de almacenamiento está en caída libre. Teléfonos de medida de almacenamiento en gigabytes. Si alojado de almacenamiento es demasiado caro, entonces no lo uso. La nube es sólo una buena idea para sistemas distribuidos geográficamente. Para todo lo demás es sólo el cumplimiento de la palabra de moda.,
    • No es sólo el tamaño de almacenamiento. Cualquier persona que ha diseñado una gran y/o de alto rendimiento de almacenamiento de datos iba a decirle lo que cualquier buen diseñador de base de datos le dirá: utilizar el tipo de datos que mejor se ajusta al tipo de dominio y no simplemente «Cambiar toda la columna de cadena de tipo NVARCHAR»
    • Todo en un contexto. Que hace búsquedas indexadas de tiempo cadenas? Base de datos de diseño es un argumento. Me dijo mi bases de datos, que no son ni muy grandes ni mal diseñado. Pero voy a enmendar la declaración, ya que hay gente ahí fuera que pueden aplicarse ciegamente.
  3. 4

    Solía usar su opción 1:

    cmd.Los parámetros.Add(«@Nombre», SqlDbType.Tipo VarChar, 20).Valor = «Bob»;

    que funcionaba bien, pero luego empecé a usar .AddWithValue y es tan simple como se pone. No me causó un problema después de muchos muchos miles de usos. La mente, casi siempre me pasa en mis clases, variables privadas, así que no tiene que preocuparse acerca de lo implícito el tipo de conversión como mucho.

  4. 3

    Depende de su aplicación. Me gustan los 2, porque yo no lke a tener que cambiar mi DAO si puedo cambiar la longitud de un procedimiento almacenado parámetro. Eso es sólo conmigo, aunque. No sé si hay penalizaciones de rendimiento ni nada.

Dejar respuesta

Please enter your comment!
Please enter your name here