SqlDataReader

C# ADO.NET: Chamada de procedimentos armazenados e SqlDataReader

Chamar procedimentos armazenados do SQL Server e ler resultados em fluxo com SqlDataReader, pontos fundamentais:

  1. SqlCommand.CommandType = CommandType.StoredProcedure define que um procedimento armazenado será executado
  2. Passar parâmetros para o procedimento armazenado usando SqlParameter
  3. ExecuteReader(CommandBehavior.CloseConnection) para ler o fluxo de dados
  4. SqlDataReader é um leitor somente leitura, de avanço sequencial e baseado em fluxo e deve ser fechado após o uso

Definição do procedimento armazenado

Você precisa criar o procedimento armazenado previamente no banco de dados antes de chamá‑lo.

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

-- Teste de chamada
exec myProc @id=5Code language: JavaScript (javascript)

Recebe o parâmetro @id e retorna registros da tabela Article onde o id seja maior que o valor informado.

Chamar procedimentos armazenados em C#

ExecuteReader retorna um SqlDataReader para obter várias linhas de dados.

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());
}Code language: C# (cs)
Liberar o Reader com using para evitar vazamento 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;//informa que o comando é um procedimento armazenado
        // adicionar parâmetro de entrada
        sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;

        // CommandBehavior.CloseConnection: fecha a conexão automaticamente quando o reader for fechado
        using (SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection))
        {
            StringBuilder sb = new StringBuilder();
            while (reader.Read())
            {
                // reader[0] primeira coluna, reader[1] segunda coluna; também aceita reader["NomeDaColuna"]
                sb.AppendLine($"{reader[0]}-{reader[1]}");
            }
            MessageBox.Show(sb.ToString());
        }
        // Não é necessário chamar reader.Close() manualmente, o using cuida da liberação automática
    }
}Code language: C# (cs)

Os três valores de enumeração CommandType

  • CommandType.Text: executar instruções SQL comuns
  • CommandType.StoredProcedure: executar procedimento armazenado
  • CommandType.TableDirect: ler diretamente uma tabela do banco

Se você não definir StoredProcedure, o programa interpretará o nome do procedimento como uma instrução SQL normal e lançará um erro!

Direções de parâmetro do SqlParameter

  • ParameterDirection.Input: parâmetro de entrada (recebe valor, mais utilizado)
  • ParameterDirection.Output: parâmetro de saída
  • ParameterDirection.InputOutput: parâmetro bidirecional entrada‑saída
  • ParameterDirection.ReturnValue: valor retornado pelo procedimento armazenado

O que faz CommandBehavior.CloseConnection

Quando SqlDataReader chamar Close() ou for liberado, a SqlConnection associada será fechada automaticamente.
Cenário ideal: quando um método retorna um objeto Reader, a conexão é recuperada após o código externo terminar a leitura dos dados.

Características importantes do SqlDataReader

  1. Somente leitura e avanço sequencial: só percorre registros para frente com Read(), não permite voltar nem alterar dados
  2. Mantém a conexão ocupada: enquanto o Reader estiver aberto, a conexão com o banco não pode executar outras operações
  3. Recursos devem ser liberados: chame reader.Close() manualmente ou prefira a liberação automática com using
  4. Duas formas de ler colunas:
    csharp reader[0]; // leitura por índice reader["Title"]; // leitura por nome do campo (melhor legibilidade)

Avisos importantes

  1. Esquecer de configurar CommandType.StoredProcedure → falha na execução
  2. Nomes de parâmetros com diferença de letras maiúsculas/minúsculas ou grafia diferente do procedimento armazenado → parâmetros não correspondem
  3. Reader não fechado → conexão permanece ocupada e esgota o pool de conexões
  4. Executar novas consultas dentro de while(reader.Read()): uma mesma conexão não suporta múltiplos leitores ativos ao mesmo tempo
  5. Parâmetros faltantes ou tipos incompatíveis no procedimento armazenado → erro em tempo de execução

Comparação

Método de execuçãoCenário de usoObjeto retornado
ExecuteNonQueryProcedimentos armazenados para inserir, atualizar e excluirint linhas afetadas
ExecuteScalarRetornar uma única linha e coluna (consultas de agregação)object
ExecuteReaderRetornar conjuntos de dados com várias linhasSqlDataReader (leitura em fluxo)

SqlDataReader

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *