SqlDataReader

C# ADO.NET: Llamada a procedimientos almacenados y SqlDataReader

Llamar procedimientos almacenados de SQL Server y leer resultados mediante flujo con SqlDataReader, puntos clave:

  1. SqlCommand.CommandType = CommandType.StoredProcedure marca que se ejecutará un procedimiento almacenado
  2. Pasar parámetros al procedimiento almacenado usando SqlParameter
  3. ExecuteReader(CommandBehavior.CloseConnection) para leer el flujo de datos
  4. SqlDataReader es un lector solo lectura y de avance secuencial basado en flujo que debe cerrarse después de usarlo

Definición del procedimiento almacenado

Debes crear previamente el procedimiento almacenado en la base de datos para poder invocarlo.

create proc myProc
@id int
as
select * from [dbo].[Article] where id>@id
go

-- Prueba de llamada
exec myProc @id=5Lenguaje del código: JavaScript (javascript)

Recibe el parámetro @id y devuelve registros de la tabla Article donde el valor de id sea mayor al valor recibido.

Llamar procedimientos almacenados desde C#

ExecuteReader devuelve un objeto SqlDataReader para leer múltiples filas de datos.

string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlCommand sqlCom = new SqlCommand();
    sqlCom.Connection = conn;
    sqlCom.CommandText = "myProc";
    sqlCom.CommandType = CommandType.StoredProcedure;

    SqlParameter param = new SqlParameter("@id", SqlDbType.Int, 8);
    param.Value = 4;
    param.Direction = ParameterDirection.Input;
    sqlCom.Parameters.Add(param);

    SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
    StringBuilder sb = new StringBuilder();
    while (reader.Read())
    {
        sb.AppendLine(reader[0] + "-" + reader[1]);
    }
    reader.Close();
    MessageBox.Show(sb.ToString());
}Lenguaje del código: C# (cs)
Liberar el Reader con using para evitar fugas de recursos
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand sqlCom = new SqlCommand("myProc", conn))
    {
        sqlCom.CommandType = CommandType.StoredProcedure;//indica que el comando es un procedimiento almacenado
        // agregar parámetro de entrada
        sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;

        // CommandBehavior.CloseConnection: cierra automáticamente la conexión al cerrar el reader
        using (SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection))
        {
            StringBuilder sb = new StringBuilder();
            while (reader.Read())
            {
                // reader[0] primera columna, reader[1] segunda columna; también se puede usar reader["NombreColumna"]
                sb.AppendLine($"{reader[0]}-{reader[1]}");
            }
            MessageBox.Show(sb.ToString());
        }
        // No hace falta llamar manualmente a reader.Close(), using libera los recursos automáticamente
    }
}Lenguaje del código: C# (cs)

Los tres valores de enumeración de CommandType

  • CommandType.Text: ejecutar sentencias SQL normales
  • CommandType.StoredProcedure: ejecutar procedimiento almacenado
  • CommandType.TableDirect: leer directamente una tabla de base de datos

Si no configuras StoredProcedure, el programa interpreta el nombre del procedimiento como una sentencia SQL común y lanzará un error.

Direcciones de parámetro en SqlParameter

  • ParameterDirection.Input: parámetro de entrada (pasar valores, el más usado)
  • ParameterDirection.Output: parámetro de salida
  • ParameterDirection.InputOutput: parámetro bidireccional entrada‑salida
  • ParameterDirection.ReturnValue: valor devuelto por el procedimiento almacenado

Funcionamiento de CommandBehavior.CloseConnection

Cuando se invoca Close() o se libera el objeto SqlDataReader, se cierra automáticamente el SqlConnection asociado.
Escenario útil: cuando un método devuelve un objeto Reader, la conexión se recupera automáticamente una vez que el código externo termina de leer los datos.

Características importantes de SqlDataReader

  1. Solo lectura y avance secuencial: solo se puede avanzar con Read(), no retroceder ni modificar registros
  2. Ocupa la conexión: mientras el Reader esté abierto, la conexión de base de datos no puede ejecutar otras operaciones
  3. Es obligatorio liberar recursos: llamar manualmente a reader.Close() o usar preferiblemente using para liberación automática
  4. Dos formas de leer columnas:
    csharp reader[0]; // lectura por índice reader["Title"]; // lectura por nombre de campo (más legible)

Advertencias

  1. Olvidar configurar CommandType.StoredProcedure → error de ejecución
  2. Mayúsculas, minúsculas o escritura incorrecta en nombres de parámetros respecto al procedimiento almacenado → fallo de coincidencia
  3. No cerrar el Reader → la conexión permanece ocupada y se agota el grupo de conexiones
  4. Ejecutar nuevas consultas dentro de while(reader.Read()): una misma conexión no admite varios lectores activos al mismo tiempo
  5. Falta de parámetros o tipos incompatibles en el procedimiento almacenado → error en tiempo de ejecución

Comparación

Método de ejecuciónCasos de usoObjeto devuelto
ExecuteNonQueryProcedimientos almacenados para insertar, actualizar y eliminarint filas afectadas
ExecuteScalarDevolver una sola fila y una sola columna (consultas de agregación)object
ExecuteReaderDevolver conjuntos de datos de varias filasSqlDataReader (lectura por flujo)

SqlDataReader

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *