ADO .NET - Usando Stored Procedures no MySQL (revisão para iniciantes)


Este artigo trata de como usar stored procedures no MySQL com ADO .NET.

Do que você vai precisar ?

Todas as ferramentas citadas são grátis, basta você acessar os links e baixar cada ferramenta e instalar.

Parte 1 - Definindo o banco de dados e as tabelas no MySQL via MySQL Administrator

Abra o MySQL Administrator e clique em Catalogs para visualizar os banco de dados existentes;

Neste exemplo eu vou usar o banco de dados Cadastro e a tabela Clientes que tem a seguinte estrutura:

Para criar o banco de dados Cadastro clique com o botão direito do mouse sob a área esquerda inferior abaixo de Schemata e selecione - Create New Schema - informando o nome do banco de dados Cadastro;

A seguir clique com o botão direito sobre o banco de dados Cadastro e selecione - Create New Table - definindo a estrutura acima mostrada e salvando a tabela com o nome Clientes;

Para incluir dados na tabela Clientes abra o MySQL Query Browser, selecione o banco de dados Cadastro; A seguir defina a instrução SQL INSERT INTO conforme abaixo:

insert into clientes values(4,'Teste','teste@test.com.br','Lins', 45)

Após clicar no botão para executar a consulta os dados serão salvos no banco de dados. Você pode repetir esta operação até quando achar necessário.

Para ver os dados incluídos clique sobre a tabela Clientes e execute o comando SELECT gerado:

Seguindo as orientações acima vamos criar também a tabela Produtos com a estrutura abaixo:

Aproveite e inclua alguns registros na tabela usando a instrução SQL - INSERT INTO.

Exemplo : insert into produtos values (4,'Mouse',30)

Dessa forma temos o banco de dados Cadastro e duas tabelas : Clientes e Produtos.

Realmente muito simples...

Parte 2 - Definindo as stored Procedures no MySQL via MySQL Administrator

Stored procedures e funções são recursos novos no MySQL e estão disponíveis a partir da versão 5.0. Uma stored procedure é um conjunto de comandos SQL que podem ser armazenados no servidor. Uma vez que isto tenha sido feito, os clientes não precisam de reenviar os comandos individuais mas podem fazer referência às stored procedures.

Stored procedures podem fornecer um aumento no desempenho já que menos informação precisa ser enviada entre o servidor e o cliente. O lado negativo é que isto aumenta a carga no sistema do servidor de banco de dados, já que a maior parte do trabalho é feita no servidor e menor parte é feita do lado do cliente (aplicação). E geralmente existem muitas máquinas clientes (como servidores web) mas apenas um ou poucos servidores e banco de dados.

O MySQL segue a sintaxe SQL:2003 para stored procedures, que também é usada pelo DB2 da IBM. Suporte para compatibilidade de outras linguagens de stored procedures (PL/SQL, T-SQL) podem ser adicionadas posteriormente.

Vamos criar as stored procedures que iremos usar no artigo. Para isso abra o SQL Administrator (podemos criar também no MySQL Query Browser)

- Clique na aba Stored procedures;
- Clique no botão - Create Stored Proc;
- Informe o nome da Store Procedure e clique no botão - Create PROCEDURE;

Como exemplo estou criando a procedure sp_GetTodosClientes:

CREATE PROCEDURE - Comando que vai criar procedure. Entre os comandos BEGIN e END é que serão colocados os comandos executados pela procedure.

Para esta procedure informe o comando Select * from clientes; e clique no botão Execute SQL;

Se não houver erros você verá o nome da procedure exibida na janela.

Você também pode editar e excluir uma procedure usando os botões Edit Store Proc e Drop Stored Proc;

Vamos criar a procedure para retornar um cliente pelo seu código repetindo o passos indicados acima e informando o nome sp_GetCliente;

A seguir informe o código abaixo na janela do Editor:

Observe que existe um parâmetro para esta procedure: o código do tipo INT.

Os parâmetros podem ser IN, apenas de entrada, OUT, apenas de saída e INOUT, entrada e saída. No nosso caso temos um parâmetro de entrada.

Os tipos de dados dos parâmetros são os mesmo tipos de dados do MySQL (INT, VARCHAR(45), TEXT, BLOB...). No exemplo o parâmetro é do tipo INT.

O comando IF esta verificando se foi passado o parâmetro para a procedure.

Se não foi passado o comando irá selecionar todos os clientes se foi passado ele irá retornar o cliente como respectivo código.

Agora vamos criar uma stored procedure que retornar os dados das duas tabelas.

Repita os passos acima para criar uma nova procedure; informe o nome sp_GetClientesProdutos e informe o código abaixo:

Ao final deveremos ver na janela de procedures as stored procedures criadas conforme figura abaixo:

Parte 3 - Criando o projeto Windows Forms no Visual C# 2010

Abra o Visual C# 2010 Express Edition e no menu File clique em New Project e selecione o template Windows Forms Application com o nome Usando_SP_MySQL;

A seguir vamos incluir uma referência ao MySQL Connector, clicando no Project -> Add Reference;

A janela Add Reference irá surgir:

Clique na aba Browse e selecione o assembly MySQL.Data.dll e clique em OK;

Tarefa 1- Como retornar diversas linhas de uma SP usando um DataReader

Se você desejar usar o DataReader (OledDb ou Sql) para ler os registros da tabela e exibir no DataGridView vai ter um pouco mais de trabalho pois não poderá atribuir o objeto DataReader a propriedade DataSource do controle datagridview.

A estratégia que você deverá seguir é a seguinte:

1- Obter quantas colunas existe na tabela;
2- Ler o nome de cada coluna e criar o cabeçalho no DataGridView;
3- Ler cada um dos registros e verificar qual o tipo de dados de cada uma das colunas;
4- Obter o valor da coluna usando o método apropriado;

Após definir os cabeçalhos das colunas no DataGridView criadas com os nomes das colunas da tabela Clientes devemos percorrer os registros e preencher o controle. Para fazer isso devemos tomar os seguintes cuidados:
- Quanto obtemos o dado de um coluna em um DataReader temos que especificar o tipo de dados pois a um método para cada tipo de dados; assim em uma coluna do tipo Integer devemos usar o método GetInt32() para obter o valor.
- Então temos que percorrer cada linha da tabela e verificar em cada coluna qual o tipo de dados para usar o método adequado e obter o seu valor;
- Para saber o tipo de dados de um coluna usaremos o método GetFieldType() verificando se o mesmo é uma string (System.String) ou um inteiro (System.UInt32) ou uma data (System.Date).

Então no formulário form2.cs inclua um controle DataGridView (name= gdvDados) e um controle Button (btnGetTodosClientes);A seguir defina o seguinte código no evento Click do botão de comando:

   private void btnGetTodosClientes_Click(object sender, EventArgs e)
        {
            string strConn = "Server=localhost;Database=Cadastro;Uid=root;Pwd=******;Connect Timeout=30;";
            MySqlConnection cn = new MySqlConnection(strConn);
            MySqlCommand cmd = new MySqlCommand();
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "sp_GetTodosClientes";
                cmd.Connection = cn;
                try
                {
                    cmd.Connection.Open();
                    MySqlDataReader dr = cmd.ExecuteReader();

                    //Obtem o número de colunas
                    int nColunas = dr.FieldCount;

                    //percorre as colunas obtendo o seu nome e incluindo no DataGridView
                    for (int i = 0; i < nColunas; i++)
                    {
                        dgvDados.Columns.Add(dr.GetName(i).ToString(), dr.GetName(i).ToString());
                    }

                    //define um array de strings com nCOlunas
                    string[] linhaDados = new string[nColunas];
                    //percorre o DataRead
                    while (dr.Read())
                    {
                         //percorre cada uma das colunas
                         for (int a=0; a < nColunas; a++)
                        {
                          //verifica o tipo de dados da coluna
                          if (dr.GetFieldType(a).ToString() == "System.UInt32")
                          {
                                linhaDados[a] = dr.GetInt32(a).ToString();
                          }
                          if (dr.GetFieldType(a).ToString() == "System.String")
                          {
                               linhaDados[a] = dr.GetString(a).ToString();
                          }
                          if (dr.GetFieldType(a).ToString() == "System.DateTime")
                          {
                               linhaDados[a] = dr.GetDateTime(a).ToString();
                          }
                         }
                         //atribui a linha ao datagridview
                         dgvDados.Rows.Add(linhaDados);
                       }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro :: " + ex.Message);
                }
                finally
                {
                    cmd.Connection.Close();
                    cmd.Dispose();
                }
            }
        }//fim

Resultado Obtido:

Tarefa 2- Como retornar diversas linhas de uma SP usando um DataAdapter

Para usar um DataAdapter teremos que realizar as seguintes operações:

  1. Criar e abrir um conexão com o MySQL
  2. Criar um objeto MySQLCommand
  3. Criar um objeto Adapter baseado no objeto Command
  4. Atribuir o objeto Connection ao objeto MySQLAdapter
  5. Executar a stored procedure usando o método Fill e atribuir o resultado a um objeto DataTable
  6. Liberar o MySQLDataAdapter

Para cumprir esses procedimentos inclua o código abaixo no formulário form3.cs:

Namespaces usados:

using System;
using System.Data;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

Código do evento Click do botão de comando:

  private void button1_Click(object sender, EventArgs e)
        {
            MySqlDataAdapter da = null;
            DataTable dt = null;
            MySqlConnection cn = null;
            MySqlCommand cmd = null;
            try
            {
                string strConn = "Server=localhost;Database=Cadastro;Uid=root;Pwd=*****;Connect Timeout=30;";
                cn = new MySqlConnection(strConn);
                cmd = new MySqlCommand();
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "sp_GetTodosClientes";
                    cmd.Connection = cn;
                }
                dt = new DataTable();
                da = new MySqlDataAdapter(cmd);
                da.Fill(dt);
                this.gdvDados.DataSource = dt;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message);
            }
            finally
            {
                da.Dispose();
                cmd.Dispose();
                dt.Dispose();
                cn.Close();
            }
        }

Resultado obtido:

Tarefa 3- Como retornar uma única linha de uma SP usando um DataAdapter

Para retornar um única linha retornada pela stored procedure sp_GetCliente passamos o código do cliente como parâmetro e estamos obtendo a primeira linha do DataTable usando a linha de código :

Dim dr As DataRow = dt.Rows[0]

E depois atribuímos os valores da coluna aos controles TextBox do formulário form4.cs:

this.txtCodigo.Text = dr["id"].ToString();
this.txtNome.Text = dr["nome"].ToString();
this.txtEmail.Text = dr["email"].ToString();
this.txtCidade.Text = dr["cidade"].ToString();
this.txtIdade.Text = dr["idade"].ToString();

O código do formulário form4.cs é dado a seguir:

Namespaces usados:

using System;
using System.Data;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

O código do evento Click do botão de comando:

    private void btnExecuta_Click(object sender, EventArgs e)
        {
            if (txtCodigo.Text == string.Empty)
            {
                MessageBox.Show("Informe o código do cliente.");
                txtCodigo.Focus();
                return;
            }

            string strConn = "Server=localhost;Database=Cadastro;Uid=root;Pwd=*****;Connect Timeout=30;";
            MySqlConnection cn = new MySqlConnection(strConn);

            MySqlCommand cmd = new MySqlCommand();
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "sp_GetCliente";
                cmd.Parameters.AddWithValue("@_codigo", Int32.Parse(txtCodigo.Text));
                cmd.Connection = cn;
            }

            DataTable dt = new DataTable();
            MySqlDataAdapter da = new MySqlDataAdapter(cmd);
            da.Fill(dt);
            da.Dispose();
            cmd.Dispose();
            cn.Close();
            DataRow dr = dt.Rows[0];
            this.txtCodigo.Text = dr["id"].ToString();
            this.txtNome.Text = dr["nome"].ToString();
            this.txtEmail.Text = dr["email"].ToString();
            this.txtCidade.Text = dr["cidade"].ToString();
            this.txtIdade.Text = dr["idade"].ToString();
            dt.Dispose();
        }

O resultado obtido é visto abaixo:

Neste caso estamos informando o código do cliente na caixa de texto txtCodigo que será usado pela stored procedure sp_GetClientesProdutos;

 Tarefa 4 - Como retornar múltiplos resultsets usando um DataAdapter

As etapas a serem cumpridas são muito parecidas com as dos exemplos anteriores.

Ao ser executada a stored procedure permitira que se obtenha uma lista dos clientes e dos produtos que serão exibidos em dois controles DataGridView.

A seguir vemos o código do formulário form5.cs :

Namespaces usados:

using System;
using System.Data;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

Código do evento Click do botão - Retornando Múltiplos resultsets via DataAdapter :

private void btnExecutaSP_Click(object sender, EventArgs e)
{
MySqlConnection cn = new MySqlConnection("Server=localhost;Database=Cadastro;Uid=root;Pwd=*****;Connect Timeout=30;");
MySqlCommand cmd = new MySqlCommand();

{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_getClientesProdutos";
cmd.Connection = cn;
}
DataSet ds = new DataSet();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(ds);
da.Dispose();
cmd.Dispose();
cn.Close();
this.gdvClientes.DataSource = ds.Tables[0];
this.gdvProdutos.DataSource = ds.Tables[1];
ds.Dispose();

}

Note que obtemos um dataset com duas tabelas contendo as informações dos clientes e dos produtos.

O resultado obtido é visto abaixo:

Cada controle DataGridView exibe o retorno da stored procedure obtido do dataset.

Pegue o projeto completo com os exemplos aqui : Usando_SP_MySQL.zip

1Pedro 1:3 Bendito seja o Deus e Pai de nosso Senhor Jesus Cristo, que, segundo a sua grande misericórdia, nos regenerou para uma viva esperança, pela ressurreição de Jesus Cristo dentre os mortos,
1Pedro 1:4
para uma herança incorruptível, incontaminável e imarcescível, reservada nos céus para vós,

1Pedro 1:5
que pelo poder de Deus sois guardados, mediante a fé, para a salvação que está preparada para se revelar no último tempo;

Referências:


José Carlos Macoratti