C# - ADO .NET para Iniciantes - III - Command (SqlCommand)


Este é um mini-curso sobre ADO .NET para iniciantes usando a linguagem C#.  

Esta chegando agora ???

Então acompanhe os dois primeiros artigos:

Os requisitos mínimos para que você aproveite este minicurso é possuir um pouco de conhecimento sobre lógica de programação.

Se você não conhece a linguagem C# pode ler os seguintes artigos :

Se você já conhece VB .NET e esta querendo a aprender C# sugiro que você leia o meu artigo:

O material necessário para acompanhar o curso é: (Irei utilizar o Visual C# 2008 Express Edition)

1- Visual C# 2008 Express Edition
2- SharpDevelop 2.2
3- SQL Server 2005 Express Edition

Todos esses programas são gratuitos e portanto você não vai gastar um centavo neste curso.

Durante o curso vamos desenvolver uma aplicação com acesso a dados usando C# de forma que você irá fazendo e aprendendo na prática os principais conceitos básicos envolvidos.

Mas chega de papo e vamos ao que interessa...

Falando um pouco sobre o objeto SqlCommand

O objetivo desta aula é descrever o objeto SqlCommand e como você pode usá-lo para interagir com um banco de dados. Resumindo os objetivos são:

Veja na tabela a seguir um resumo para cada um dos métodos citados:

Método Descrição
ExecuteReader Executa a consulta e retorna um objeto SqlDataReader;
ExecuteNonQuery Executa a consulta e não retorna nenhuma coleção. Usado para instruções INSERT, DELETE e UPDATE onde retorna o número de registros afetados.
Ex:

    SqlCommand sqlComm = new SqlCommand("DELETE FROM Categories WHERE CategoryID=1", sqlConn);
     sqlComm.ExecuteNonQuery();
ExcecuteScalar Executa a consulta e retorna um único valor.(uma linha e uma coluna)

Introdução

Um objeto SqlCommand permite que você especifique qual tipo de interação você deseja realizar em um banco de dados: selecionar, incluir, modificar e excluir dados e pode ser usado para dar suporte em operações em um cenário de gerenciamento de dados no modelo desconectado mas irei focar nesta aula como usar o SqlCommand de forma simples e isolada.

A classe SqlCommand é usada para representar uma instrução SQL ou stored procedure disparada com o objetivo de inserir, atualizar, excluir ou selecionar informações de uma fonte de dados. A sua posição na hierarquia de classes da plataforma .NET é dada a seguir:

System.Object
  System.MarshalByRefObject
    System.ComponentModel.Component
      System.Data.Common.DbCommand
        System.Data.Odbc.OdbcCommand
        System.Data.OleDb.OleDbCommand
        System.Data.OracleClient.OracleCommand
        System.Data.SqlClient.SqlCommand
        System.Data.SqlServerCe.SqlCeCommand

Para criar um objeto SqlCommand podemos usar um construtor criando uma instância da classe SqlCommand passando a string SQL que representa qual operação desejamos realizar contra o banco de dados e o objeto SqlConnection que deverá ter sido criado anteriormente contendo a conexão com a fonte de dados:

SqlCommand cmd = new SqlCommand("select * from Clientes", conn);

Podemos então realizar as seguintes operações com o objeto SqlCommand:

Nos exemplos abaixo irei usar uma tabela chamada Clientes com a seguinte estrutura:
  • id - int - primary Key
  • nome - varchar(50)
  • email - varchar(50)

1- Consultar dados

Para consultar dados você usa uma instrução SQL SELECT para retornar um conjunto de dados para visualização.

Para obter este resultado você pode usar o método ExecuteReader o qual retorna um objeto SqlDataReader da seguinte forma:

// 1. Instancia um novo comando com uma consulta e uma conexão
SqlCommand cmd = new SqlCommand("select * from Clientes", conn);

// 2. Chama o método ExecuteReader para obter o resultado da consulta
SqlDataReader dr = cmd.ExecuteReader();

2- Incluir dados

Para inserir registros em um banco de dados use o método ExecuteNonQuery do objeto SqlCommand :

// prepara um comando SQL para incluir dados usando a instrução INSERT INTO
string  incluiSQL = @" insert into Clientes (Nome, Email) values ('Macoratti', 'macoratti@ig.com.br')";

// 1.
Instancia um novo comando com uma consulta e uma conexão
SqlCommand cmd = new SqlCommand(incluiSQL , conn);

// 2. Chama o método ExecuteNonQuery para enviar o comando
cmd.ExecuteNonQuery();

 

Aqui alteramos ligeiramente a forma de instanciar um objeto SqlCommand passando a variável incluiSQL como parâmetro.

Um detalhe importante é que estamos incluindo valores para os campos Nome e Email mas a tabela possui um campo id que é a chave primária que não faz parte da instrução. Isto é devido ao fato da inclusão deste campo ser feita de forma automática pelo SQL Server. Se você tentar incluir um valor para o campo id no código irá obter uma exceção em tempo de execução.

3- Atualizar dados


O método ExecuteNonQuery também é usado para atualização de dados:


// prepara um comando SQL para incluir dados usando a instrução Update
string atualizaSQL = @"update Clientes set Nome = 'Macoratti'  where id = 1";

// 1.
Instancia um novo comando com uma consulta sql
SqlCommand cmd = new SqlCommand(atualizaSQL );

// 2.  Define a propriedade Connection
cmd.Connection = conn;

// 3.
Chama o método ExecuteNonQuery para enviar o comando
cmd.ExecuteNonQuery();

 

Neste código usamos um construtor SqlCommand que possui somente um comando, logo em seguida nós atribuímos o objeto SqlConnection (conn) usando a propriedade Connection do objeto SqlCommand cmd;
 

Com isso mostramos que podemos alterar o objeto Connection a qualquer tempo.


4- Excluir dados


O método ExecuteNonQuery também é usado para excluir dados:

// prepara um comando SQL para incluir dados usando a instrução DELETE
string excluiSQL = @"delete from Clientes where id = 1";


// 1. Instantcia um novo comando
SqlCommand cmd = new SqlCommand();

// 2. Define a propriedade CommandText
cmd.CommandText =
excluiSQL ;

// 3.
Define a propriedade Connection
cmd.Connection = conn;

// 4.
 Chama o método ExecuteNonQuery para enviar o comando
cmd.ExecuteNonQuery();


Neste exemplo usamos o construtor SqlCommand sem parâmetros mas logo em seguida definimos explicitamente as propriedades CommandText e Connection do objeto SqlCommand, cmd.

Com isso mostramos que podemos alterar o objeto Connection  e Command a qualquer tempo.
 

5- Obtendo valores


Às vezes tudo o que você precisa do banco de dados é um valor único que pode ser o resultado de uma contagem, soma, média, ou  outro valor agregado. Usar um ExecuteReader e calcular o resultado no seu código não é a forma mais eficiente de fazer isso. A melhora maneira é deixar o banco de dados realizar a operação e retornar apenas um valor único como resultado. Para isso usamos o método ExecuteScalar:


// 1.
Instantcia um novo comando
SqlCommand cmd = new SqlCommand("select count(*) from Clientes", conn);

// 2. Chama o método  ExecuteScalar para enviar o comando
int count = (int)cmd.ExecuteScalar();

 

A consulta no construtor SqlCommand obtém a contagem de todos os registros a partir da tabela Clientes e irá retornar somente o valor da contagem.

O método ExecuteScalar retorna um valor do tipo Object, temos que efetuar uma coerção forçada (casting) para converter o valor para um int.

 

using System.Data.SqlClient;
namespace adonetCshp_3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            string connetionString = null;
            SqlConnection cnn = default(SqlConnection);
            SqlCommand cmd = default(SqlCommand);
            string sql = null;
            connetionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=SSPI";
   
            sql = "Select Count(*) from clientes";
            cnn = new SqlConnection(connetionString);

            try
            {
                cnn.Open();
                cmd = new SqlCommand(sql, cnn);
                Int32 contador = Convert.ToInt32(cmd.ExecuteScalar());
                cmd.Dispose();
                cnn.Close();
                MessageBox.Show(" No. de linhas " + contador );
            }
            catch (Exception ex)
            {
                MessageBox.Show("Não foi possível abrir a conexão com o banco de dados ! " + ex.Message.ToString());
            } 
        }
    }
}


A seguir um exemplo realizando as operações CRUD na tabela Clientes do banco de dados Cadastro.mdf:
 

using System;
using System.Data;
using System.Data.SqlClient;
class ExecutaInsertUpdateDelete
{
   public static void exibirRegistro(SqlCommand comando, string ID)
   {
     comando.CommandText ="SELECT codigo, nome FROM Clientes WHERE codigo = '" + ID + "'";
     SqlDataReader dr = comando.ExecuteReader();
     while (dr.Read())
     {
       listBox1.Items.Add("dr[\" codigo\"] = " +  dr["codigo"]);
       listBox1.Items.Add("dr[\" nome\"] =  "  + dr["Nome"]);
     }
     dr.Close();
   }
   public static void Main()
   {
    connetionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=SSPI";
    SqlConnection conexaoSql =new SqlConnection(connetionString) ;
    SqlCommand comando = conexaoSql.CreateCommand();
    comando.CommandText ="INSERT INTO Clientes (codigo, nome) VALUES (" + " 19, 'Macoratti')";
    conexaoSql.Open();
    int numeroLinhasAfetadas = comando.ExecuteNonQuery();
    l

     listBox1.Items.Add("Numero de linhas afetadas = " + numeroLinhasAfetadas);
    exibirRegistro(comando, "9");

    comando.CommandText = "UPDATE Clientes SET Nome = 'Novo'  WHERE codigo = 19";
    numeroLinhasAfetadas = comando.ExecuteNonQuery();
    listBox1.Items.Add("Numero de linhas atualizadas = " + numeroLinhasAfetadas);
    exibirRegistro(comando, "9");
    comando.CommandText ="DELETE FROM Clientes WHERE codigo = 19";
    numeroLinhasAfetadas = comando.ExecuteNonQuery();
    listBox1.Items.Add("Numero de linhas deletadas = " + numeroLinhasAfetadas);
    conexaoSql.Close();
   }
}

Para encerrar eu gostaria de falar sobre o bloco using:

A instrução using  declara o início de um bloco Using e opcionalmente adquire os recursos do sistema que o bloco controla.

Um bloco Using garante a liberação de um ou mais dos tais recursos quando seu código estiver finalizado com eles. Isso torna-os disponíveis para uso por outros códigos.

As Classes SqlConnection e SqlCommand implementam a interface IDisposable e isto significa que eles podem usar recursos não gerenciados e liberar tais recursos é trabalho do desenvolvedor, de forma que depois de usar estas classes temos que chamar o método Dispose().

Se ocorrer uma exeção no acesso ao banco de dados temos que ter certeza que o Dispose() foi chamado , este é um motivo para usar a palavra reservada Using.

Obs: Recursos gerenciados são descartados pela coletor de lixo .NET Framework (GC) sem qualquer codificação extra de sua parte. Você não precisa de um bloco Using para recursos gerenciados.

Veja abaixo um exemplo de bloco Using para criar uma tabela em um banco de dados;  a string de conexão esta sendo obtida a partir do arquivo de configuração

    using (SqlConnection con = new SqlConnection(Macoratti.Properties.Settings.Default.MacorattiConnectionString))
    {
        con.Open();
        try
        {
            using (SqlCommand command = new SqlCommand("CREATE TABLE Macoratti (Codigo INT, Nome TEXT, Endereco TEXT)", con))
            {
                command.ExecuteNonQuery();
            }
        }
        catch
        {
            Console.WriteLine("Tabela não pode ser criada");
        }
    }

Outro exemplo usando Using e comparando com a sintaxe tradicional sem usar Using:

using (SqlConnection cn = new SqlConnection(connectionString))
{
    using (SqlCommand cm = new SqlCommand(commandString, cn))
    {
        cn.Open();
        cm.ExecuteNonQuery();
    }
}

 

SqlConnection cn =  null;
SqlCommand cm = null;

try
{
    cn = new SqlConnection(connectionString);
    cm = new SqlCommand(commandString, cn);
    cn.Open();
    cm.ExecuteNonQuery();
}
finally
{
    if (null != cm);
        cm.Dispose();
    if (null != cn)
        cn.Dispose();
}

Os dois trechos de código acima são equivalentes.

No próximo artigo irei falar sobre o objeto SqlDataReader.

Eu sei é apenas C# mas eu gosto...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti