¿Cuál es el mejor método para pasar parámetros a SQLCommand?
-
08-07-2019 - |
Pregunta
¿Cuál es el mejor método para pasar parámetros a SQLCommand? Puedes 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 términos de rendimiento o de verificación de errores. Pero me gustaría saber más definitivamente.
Solución
También puede usar AddWithValue ()
, pero tenga en cuenta la posibilidad de una conversión de tipo implícita incorrecta.
cmd.Parameters.AddWithValue("@Name", "Bob");
Otros consejos
¿Qué está pasando allí?
Usted cita las listas de parámetros para varias sobrecargas de Add
. Estos son métodos convenientes que corresponden directamente a las sobrecargas del constructor para la clase SqlParameter
. Básicamente, construyen el objeto de parámetro utilizando cualquier constructor que tenga la misma firma que el método de conveniencia que llamó, y luego llaman a SqlParameterCollection.Add (SqlParameter)
de esta manera:
SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);
AddWithValue
es similar pero lleva la conveniencia aún más lejos, también establece el valor. Sin embargo, en realidad se introdujo para resolver un defecto del marco. Para citar MSDN,
La sobrecarga de
Add
que requiere un cadena y un objeto quedó en desuso debido a la posible ambigüedad con elSqlParameterCollection.Add
sobrecarga que toma unaString
y unSqlDbType
valor de enumeración donde pasar un entero con la cadena podría ser interpretado como el bien valor del parámetro o el correspondienteSqlDbType
valor. UtiliceAddWithValue
cuando quieras agregar un parámetro especificando su nombre y valor.
Las sobrecargas del constructor para la clase SqlParameter
son meras comodidades para establecer propiedades de instancia. Acortan el código, con un impacto marginal en el rendimiento: el constructor puede omitir los métodos de establecimiento y operar directamente en miembros privados. Si hay una diferencia, no será mucho.
¿Qué debo hacer?
Tenga en cuenta lo siguiente (de MSDN)
Para bidireccional y salida parámetros y valores de retorno, usted debe establecer el valor de
Size
. Esto es no es necesario para los parámetros de entrada, y si no se establece explícitamente, el valor es inferido del tamaño real de la parámetro especificado cuando un se ejecuta la sentencia parametrizada.
El tipo predeterminado es input. Sin embargo, si permite inferir el tamaño de esta manera y recicla el objeto de parámetro en un bucle (usted dijo que estaba preocupado por el rendimiento), entonces el tamaño se establecerá por el primer valor y los valores posteriores que sean más largos cortado. Obviamente, esto es significativo solo para valores de longitud variable como cadenas.
Si está pasando el mismo parámetro lógico repetidamente en un bucle, le recomiendo que cree un objeto SqlParameter fuera del bucle y lo dimensione adecuadamente. El sobredimensionamiento de un varchar es inofensivo, por lo que si es un PITA para obtener el máximo exacto, simplemente configúrelo más grande de lo que espera que sea la columna. Debido a que está reciclando el objeto en lugar de crear uno nuevo para cada iteración, el consumo de memoria durante la duración del ciclo probablemente disminuirá incluso si se emociona un poco con el sobredimensionamiento.
A decir verdad, a menos que procese miles de llamadas, nada de esto hará mucha diferencia. AddWithValue
crea un nuevo objeto, evitando el problema del tamaño. Es corto, dulce y fácil de entender. Si recorres miles, usa mi enfoque. Si no lo hace, use AddWithValue
para mantener su 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 nuevos tipos de fechas, y también hay un problema que no se me pasó por la cabeza hasta que un problema reciente con las fechas me hizo pensar en las implicaciones de la ampliación.
El ensanchamiento y el estrechamiento, para aquellos que no están familiarizados con los términos, son cualidades de las conversiones de tipos de datos. Si asigna un int a un doble, no hay pérdida de precisión porque el doble es "más ancho". Siempre es seguro hacer esto, por lo que la conversión es automática. Esta es la razón por la que puede asignar un int a un doble, pero en el otro sentido tiene que hacer una conversión explícita: doble a int es una conversión más estrecha con una posible pérdida de precisión.
T
Yo diría # 1 con seguridad. Pero, sin embargo, Microsoft lo hace en el bloque de aplicaciones de acceso a datos en la biblioteca de la empresa, es el mejor, especialmente para el servidor SQL:
Solía ??usar su opción 1:
cmd.Parameters.Add (" @ Name " ;, SqlDbType.VarChar, 20) .Value = " Bob " ;;
que funcionó bien, pero luego comencé a usar .AddWithValue y es tan simple como parece. No me ha causado un problema después de muchos miles de usos. Eso sí, casi siempre paso las variables privadas de mis clases, así que no tengo que preocuparme tanto por la conversión de tipo implícita.
Depende de su aplicación. De hecho, me gusta 2, porque no quiero tener que cambiar mi DAO si cambio la longitud de un parámetro de proceso almacenado. Aunque solo soy yo. No sé si hay penalizaciones de rendimiento o algo así.