Índice de la sección dedicada a .NET (en el Guille) ADO .NET

Cuando usar ExecuteNonQuery o ExecuteScalar

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í.)

 

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


Ir al índice principal de el Guille