Publicado el 29/May/2006
Actualizado el 29/May/2006
Autor: Guillermo 'guille' Som
En este artículo veremos cómo y cuando usar el método ExecuteNonQuery o ExecuteScalar de un comando (o clase) derivado de la clase abstracta (no instanciable) DbCommand si trabajas con Visual Studio 2005 o de la interfaz IDbCommand si trabajas con cualquier versión de Visual Studio para .NET.
Introducción
En este artículo veremos cómo y cuando usar el método ExecuteNonQuery o ExecuteScalar de un comando (o clase) derivado de la clase abstracta (no instanciable) DbCommand si trabajas con Visual Studio 2005 o de la interfaz IDbCommand si trabajas con cualquier versión de Visual Studio para .NET.
Esto es lo que nos dice la ayuda de Visual Studio sobre el método ExecuteNonQuery:
Ejecuta una instrucción SQL en un objeto de conexión.
Se puede utilizar ExecuteNonQuery para realizar operaciones de catálogo (por ejemplo, consultar la estructura de una base de datos o crear objetos de base de datos como tablas) o para cambiar la información de una base de datos ejecutando las instrucciones UPDATE, INSERT o DELETE.
Aunque ExecuteNonQuery no devuelva ninguna fila, los parámetros de salida o los valores devueltos asignados a los parámetros se rellenan con datos.
Para las instrucciones UPDATE, INSERT y DELETE, el valor devuelto corresponde al número de filas afectadas por el comando. Para los demás tipos de instrucciones, el valor devuelto es -1.Y esto otro sobre ExecuteScalar:
Ejecuta la consulta y devuelve la primera columna de la primera fila del conjunto de resultados que devuelve la consulta. Se omiten todas las demás columnas y filas.
Utilice el método ExecuteScalar para recuperar un único valor (por ejemplo, un valor agregado) de una base de datos.
Por tanto, podemos deducir que ExecuteNonQuery lo usaremos para ejecutar la mayoría de las instrucciones de SQL que ejecutará algo en la base de datos, pero que no devolverá un valor.
Bueno, en realidad, en algunos casos si que devolverá un valor, pero será para indicarnos, por ejemplo, si eliminamos varias filas de la tabla, devolverá el número de filas eliminadas.Por otro lado, ExecuteScalar lo usaremos cuando tengamos que ejecutar un código de SQL del que queremos recuperar la primera columna de la primera fila.
Este método devuelve un valor de tipo Object que tendremos que convertir según el valor devuelto. Por ejemplo, si queremos saber el número de registros (filas) de una tabla que cumple cierto criterio, podemos usar un comando SQL como este:
SELECT Count(*) FROM Prueba WHERE FechaAlta >= @Param1
En este caso, el valor devuelto será del tipo Int32 y será el número de filas que hay en la tabla Prueba de la base de datos indicada en el objeto Connection que previamente habremos abierto que tenga una fecha igual o superior a la indicada en el parámetro proporcionado a ese comando. Si no hay ninguna fila que cumpla ese criterio, devolverá cero.
Nota:
Instrucciones de SQL no significa que hay que usarlo con SQL Server, sino que son instrucciones en "lenguaje" SQL, que en SQL Server se conoce como T-SQL o Transact SQL, y que por tanto podemos usar con cualquier tipo de base de datos, (o casi).
Ejemplos para Visual Basic y C#
Aquí tienes un par de ejemplos de cuando usar estos dos métodos de un objeto Command de ADO.NET, como siempre, tanto para Visual Basic para .NET como para C#, con idea de que nadie se quede fuera, je, je.
Estos trozos de código forman parte de un proyecto en el que se utiliza una base de datos de SQL Server 2005 que está en un fichero y en el que se incluye varios procedimientos almacenados, dos de ellos creados con Visual Basic 2005.
La base de datos, los procedimientos almacenados de VB y el código de la utilidad espero publicarla pronto, y si cuando leas esto ya está publicada, seguramente aquí estará el link... salvo que se me olvide ponerlo, pero espero que tú que estás leyendo esto, me avises si la fecha actual es superior al 30 de junio de 2006 (es que antes no se si lo podré publicar, espero que sí.)
- Ejemplo de ExecuteNonQuery para VB
- Ejemplo de ExecuteNonQuery para C#
- Ejemplo de ExecuteScalar para VB
- Ejemplo de ExecuteScalar para C#
Y esto es todo... pronto más
Nos vemos.
Guillermo
Ejemplo ExecuteNonQuery:
ExecuteNonQuery VB:
' Agregar N datos de prueba, ' usando el procedimiento almacenado sp_InsertarVariosDatosPrueba ' creado con Visual Basic. ' Este procedimiento almacenado a su vez usa: sp_TotalFilasPrueba Dim cnn As SqlConnection = Nothing Dim cmd As SqlCommand = Nothing ' LabelAgregar.Text = "Agregando datos..." LabelAgregar.Refresh() ' Try cnn = New SqlConnection(My.Settings.cs_pruebasGuille) cmd = New SqlCommand("sp_InsertarVariosDatosPrueba", cnn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("@cuantos", SqlDbType.Int) cmd.Parameters.Add("@hastaMesActual", SqlDbType.Bit) cmd.Parameters("@cuantos").Value = CInt(Me.txtCuantos.Text) cmd.Parameters("@hastaMesActual").Value = Me.chkHastaEstemes.Checked cnn.Open() cmd.ExecuteNonQuery() LabelAgregar.Text = "Añadir datos de ejemplo (indica el número):" LabelStatus.Text = "Datos añadidos correctamente" Catch ex As Exception Me.LabelAgregar.Text = "Error: " & ex.Message LabelStatus.Text = "ERROR" Finally If cnn IsNot Nothing AndAlso cnn.State <> ConnectionState.Closed Then cnn.Close() End If End Try
ExecuteNonQuery C#:
// Agregar N datos de prueba, // usando el procedimiento almacenado sp_InsertarVariosDatosPrueba // creado con Visual Basic. // Este procedimiento almacenado a su vez usa: sp_TotalFilasPrueba SqlConnection cnn = null; SqlCommand cmd = null; // LabelAgregar.Text = "Agregando datos..."; LabelAgregar.Refresh(); // try { cnn = new SqlConnection(Settings.Default.cs_pruebasGuille); cmd = new SqlCommand("sp_InsertarVariosDatosPrueba", cnn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@cuantos", SqlDbType.Int); cmd.Parameters.Add("@hastaMesActual", SqlDbType.Bit); cmd.Parameters["@cuantos"].Value = Convert.ToInt32(this.txtCuantos.Text); cmd.Parameters["@hastaMesActual"].Value = this.chkHastaEstemes.Checked; cnn.Open(); cmd.ExecuteNonQuery(); LabelAgregar.Text = "Añadir datos de ejemplo (indica el número):"; LabelStatus.Text = "Datos añadidos correctamente"; } catch (Exception ex) { this.LabelAgregar.Text = "Error: " + ex.Message; LabelStatus.Text = "ERROR"; } finally { if (cnn != null && cnn.State != ConnectionState.Closed) { cnn.Close(); } }
Ejemplo de ExecuteScalar:
ExecuteScalar VB:
' Usar el procedimiento almacenado sp_TotalFilasPrueba ' para saber el número de filas o registros de la tabla Prueba ' El comando SQL es: ' SELECT COUNT(*) FROM Prueba Dim cnn As SqlConnection = Nothing Dim cmd As SqlCommand = Nothing ' Try ' Usar la cadena de conexión almacenada en el fichero app.config ' En este caso es para acceder a un fichero .mdf ' en el que habrá que cambiar el "path" ' por el correcto de nuestro equipo. ' Data Source=.\SQLEXPRESS;AttachDbFilename=...\pruebasGuille_SQL.mdf;Integrated Security=True cnn = New SqlConnection(My.Settings.cs_pruebasGuille) cmd = New SqlCommand("sp_TotalFilasPrueba", cnn) cmd.CommandType = CommandType.StoredProcedure cnn.Open() Dim n As Integer n = CInt(cmd.ExecuteScalar()) Me.LabelTotalFilas.Text = "Número de filas: " & n LabelStatus.Text = "Número de filas: " & n Catch ex As Exception Me.LabelTotalFilas.Text = "Error: " & ex.Message LabelStatus.Text = "ERROR" Finally If cnn IsNot Nothing AndAlso cnn.State <> ConnectionState.Closed Then cnn.Close() End If End Try
ExecuteScalar C#:
// Usar el procedimiento almacenado sp_TotalFilasPrueba // para saber el número de filas o registros de la tabla Prueba // El comando SQL es: // SELECT COUNT(*) FROM Prueba SqlConnection cnn = null; SqlCommand cmd = null; // try { // Usar la cadena de conexión almacenada en el fichero app.config // En este caso es para acceder a un fichero .mdf // en el que habrá que cambiar el "path" // por el correcto de nuestro equipo. // Data Source=.\SQLEXPRESS;AttachDbFilename=...\pruebasGuille_SQL.mdf;Integrated Security=True cnn = new SqlConnection(Settings.Default.cs_pruebasGuille); cmd = new SqlCommand("sp_TotalFilasPrueba", cnn); cmd.CommandType = CommandType.StoredProcedure; cnn.Open(); int n; n = Convert.ToInt32(cmd.ExecuteScalar()); this.LabelTotalFilas.Text = "Número de filas: " + n; LabelStatus.Text = "Número de filas: " + n; } catch (Exception ex) { this.LabelTotalFilas.Text = "Error: " + ex.Message; LabelStatus.Text = "ERROR"; } finally { if (cnn != null && cnn.State != ConnectionState.Closed) { cnn.Close(); } }
Espacios de nombres usados en este artículo:
System.Data
System.Data.SqlClient