2011-08-31 10 views
5
MySqlCommand cmd = new MySqlCommand 
        (@"INSERT INTO Table(field) VALUES('somevalue');" + 
        "SELECT * FROM table",cn); 

Esto funciona bien para mí ya que solo estoy pasando esas declaraciones a mi servidor MySQL.usando ExecuteReader en lugar de ExecuteNonQuery

¿Está bien utilizar ExecuteReader() al insertar & actualizando & eliminando?

Normalmente uso ExecuteNonQuery() en aquellos.

+5

Afortunadamente, su código real no selecciona todas las filas de la tabla en cada inserción. Eso escalará ... mal. –

+0

Realmente va a matar su rendimiento si trato de 'SELECCIONAR' DESDE toda la tabla. Acabo de establecer como ejemplo –

+0

posible duplicado de [SQLCommand.ExecuteReader() no se limita a las declaraciones de solo lectura] (http://stackoverflow.com/questions/3348012/sqlcommand-executereader-does-not-restrict-to- read-only-statements) – nawfal

Respuesta

8

Estás a empaquetar bien el INSERT extra en junto con su SELECT con ExecuteReader(). Esto está bien.

veo dos cosas que potencialmente no son bien ... nada en el código en sí mismo, sino lo que demostramos es simplificado, y el código simplificado alude a algunos posibles malas prácticas:

El primero no es aceptable que su código parece podría usar concatenación de cadenas para sustituir valores en su consulta. Algo como esto:

MySqlCommand cmd = new MySqlCommand 
       (@"INSERT INTO Table(field) VALUES('" + somevariable + "');" + 
       "SELECT * FROM table",cn); 

Eso es un gran problema, ya que abre un enorme agujero de seguridad en su aplicación.En su lugar, es necesario utilizar parámetros de consulta, por lo que el código es de la misma familia:

MySqlCommand cmd = new MySqlCommand 
       (@"INSERT INTO Table(field) VALUES(@somevalue);" + 
       "SELECT * FROM table",cn); 
cmd.Parameters.Add("@somevalue", SqlDbType.VarChar, 50).Value = somevariable; 

El otro problema potencial es que su comando y, más importante, su conexión, debe ser envuelto en un bloque try/finally (o de preferencia un bloque mediante), así:

using (var cn = new MySqlConnection("...")) 
using (var cmd = new MySqlCommand("@INSERT INTO Table(field).... ", cn)) 
{ 
    cmd.Parameters.Add(...); 
    cn.Open(); 
    using (var rdr = cmd.ExecuteReader()) 
    { 
     while (rdr.Read()) 
     { 
      //... 
     } 
    } 
} 
+0

Siempre paso la entrada de 'usuario' en el parámetro para evitar la inyección SQL y practicar el manejo de excepciones. Solo cito este como ejemplo. Desde entonces, está bien lanzar consultas por lotes a mi servidor. Gracias por la iluminación –

3

ExecuteReader

No utilizar: cuando se consulta la base de datos va a proporcionar a ciencia cierta registro exactamente 1 .

Uso: cuando la consulta de la base de datos proporcionará un conjunto de registros. Puede ser búsqueda o informe.

ExecuteNonQuery

Uso: cuando estamos hablando de un solo registro de base de datos - en la actualización, insertar, suprimir y obtener por Id.

ExecuteScalar

No utilizar: cuando se consulta la base de datos devuelve un solo valor y este valor se puede definir como parámetro en T-SQL. ExecuteNonQuery con salida parámetro (s) siempre es preferible en este caso, ya que es más flexible, mañana habrá 2 valores por lo tanto, teniendo ExecuteNonQuery no es necesario cambiar las firmas de método.

Uso: cuando la consulta de la base de datos devuelve un único valor y este valor no puede definirse como parámetro de salida, debido a la limitación de tipo T-SQL para las variables .

Reference

+0

El OP está haciendo referencia a una clase 'MySqlCommand' para MySQL, en lugar de SQL Server. –

+2

Consejo dudoso: 'use ExecuteNonQuery con parámetros de salida cuando selecciona exactamente 1 registro'? Espera espera espera. ¿En verdad está sugiriendo que declaremos * n * params de salida para cada columna en una sola fila de resultados dada? Brutal en el desarrollador de mantenimiento. –

1

Si, por el bien de estructuración, usted tiene que utilizar ExecuteReader y luego seguir adelante, sólo recuerda a disponer de (Cerrar) el lector después. Tiene un pequeño efecto en el programa, pero lo más probable es que se limite a la parte .Net, principalmente solo el consumo de memoria de una instancia de clase adicional. De hecho, ciertos proveedores de ADO.Net usan ExecuteReader detrás de ExecuteNonQuery internamente.

El problema más grande aquí es la parte SELECT * FROM table después de su consulta de inserción. Aunque no está utilizando el lector para leer los datos, aún consume más recursos para ejecutar una consulta de selección. Aquí, no debería haber diferencia en el lado de MySQL si usa ExecuteReader o ExecuteNonQuery (a menos que lea del lector, por supuesto)

Cuestiones relacionadas