CRUD C# com Stored Procedures
Agora neste artigo vamos modificar um CRUD que receberá uma nova modificação: ao invés de ter o código SQL junto ao código C#, vamos utilizar Stored procedures no SQL Server.
Este artigo demonstrará como desenvolver um CRUD básico. CRUD vem do inglês Create Read Update e Delete que em tradução livre para o português seria Criar, Ler, Atualizar, e Excluir. O CRUD é composto pelas operações básicas que uma aplicação faz a um banco de dados.
O CRUD que será mostrado neste artigo foi desenvolvido de uma forma bem simples para aqueles que realmente estão começando a dar seus primeiros passos, mais que já tenham um conhecimento básico em C# e em SQL e SQL Server, como declarar variáveis e alguns comandos da sintaxe e executar instruções SQL.
Será usado neste artigo o Visual Studio 2010, SQL Server e o SQL Server Management Studio.
Por ser destinados a iniciantes, algumas pessoas que já tem alguma experiência poderão notar que algumas partes do código poderiam ser feitas de forma diferente, utilizando melhores práticas e reaproveitamento de código, mas o objetivo deste artigo é ensinar a aquelas que nunca fizeram um CRUD ou que possuem dúvidas de como fazer, então foi feito de maneira bem simples para que todos possam entender.
O primeiro passo é criar o banco de dados que será utilizado. A Listagem 1 contém o código SQL para a criação do mesmo.
/* CRIAR BANCO DE DADOS */
CREATE DATABASE BDCADASTRO
/* SELECIONA O BANCO DE DADOS */
USE BDCADASTRO
/* CRIACÇÃO DA TABELA */
CREATE TABLE CLIENTE (
ID INT NOT NULL IDENTITY,
NOME VARCHAR(50) NOT NULL,
ENDERECO VARCHAR(50),
CEP VARCHAR(9),
BAIRRO VARCHAR(50),
CIDADE VARCHAR(50),
UF VARCHAR(2),
TELEFONE VARCHAR(15),
CONSTRAINT PK_CLIENTE PRIMARY KEY(ID)
)
Após a criação do banco de dados, crie um formulário conforme a Figura 1.
Abaixo segue a Tabela 1 com todos os controles necessário para o formulário.
Cadastro de cliente | Tipo: Form Name: frmCadastroCliente StartPosition: CenterScreen |
Id | Tipo: TextBox Name: txtId ReadOnly: True |
Nome | Tipo: TextBox Name: txtNome CharacterCasing: Upper MaxLength: 50 |
Endereço | Tipo: TextBox Name: txtEndereco CharacterCasing: Upper MaxLength: 50 |
CEP | Tipo: MaskedTextBox Name: mskCEP Mask: 00000-999 |
Bairro | Tipo: TextBox Name: txtBairro CharacterCasing: Upper MaxLength: 50 |
Cidade | Tipo: TextBox Name: txtCidade CharacterCasing: Upper MaxLength: 50 |
UF | Tipo: TextBox Name: txtUf CharacterCasing: Upper MaxLength: 2 |
Telefone | Tipo: MaskedTextBox Name: mskTelefone Mask: (99) 0000-0000 |
Barra de botões | Tipo: ToolStrip Name: toolStrip1 |
Novo | Tipo: ToolStripButton Name: tsbNovo Text: Novo |
Salvar | Tipo: ToolStripButton Name: tsbSalvar Text: Salvar |
Cancelar | Tipo: ToolStripButton Name: tsbCancelar Text: Cancelar |
Excluir | Tipo: ToolStripButton Name: tsbExcluir Text: Excluir |
Separador | Tipo: ToolStripSeparator Name: toolStripSeparator1 |
Buscar por Id: | Tipo: ToolStripLabel Name: tsbBuscaPorId Text: Buscar por Id: |
Tipo: ToolStripTextBox Name: tstId | |
Buscar | Tipo: ToolStripButton Name: tsbBuscar Text: Buscar |
As imagens para os botões podem ser encontradas no Iconfinder.com, basta apenas procurar pelo nome.
Após tudo isso feito é hora de programar.
Dê dois cliques em uma área vazia do formulário, para que seja mostrado o arquivo frmCadastroCliente.cs. Nele será criado o método frmCadastroCliente_Load. Logo acima do método frmCadastroCliente_Load existe o construtor da classe que é o frmCadastroCliente e logo acima dele crie as seguintes variáveis, conforme a Listagem 2.
string connectionString =
@"Server=.\sqlexpress;Database=bdcadastro;Trusted_Connection=True;";
bool novo;
public frmCadastroCliente()
{
InitializeComponent();
}
private void frmCadastroCliente_Load(object sender, EventArgs e)
{
}
A variável connectionString armazena a string de conexão com o banco de dados e a variável novo será usada para quando salvar saber se o que será salvo é um novo registro ou uma atualização de um registro existente.
Quando o programa for executado, alguns campos deverão aparecer desabilitados e só serão habilitados ao clicar no botão Novo, permitindo assim digitar as informações, e também alguns botões da barra também estarão inacessíveis e só poderão serem clicados dependendo da situação. Essas mudanças de estado ocorrerão a cada evento; O método frmCadastroCliente_Load é executado ao carregar o formulário e parar ter a configuração inicial do formulário coloque o seguinte código no método, conforme mostra a Listagem 3.
private void frmCadastroCliente_Load(object sender, EventArgs e)
{
tsbNovo.Enabled = true;
tsbSalvar.Enabled = false;
tsbCancelar.Enabled = false;
tsbExcluir.Enabled = false;
tstId.Enabled = true;
tsbBuscar.Enabled = true;
txtNome.Enabled = false;
txtEndereco.Enabled = false;
mskCep.Enabled = false;
txtBairro.Enabled = false;
txtCidade.Enabled = false;
txtUf.Enabled = false;
mskTelefone.Enabled = false;
}
Agora a Listagem 4 mostra o código do botão Novo.
private void tsbNovo_Click(object sender, EventArgs e)
{
tsbNovo.Enabled = false;
tsbSalvar.Enabled = true;
tsbCancelar.Enabled = true;
tsbExcluir.Enabled = false;
tstId.Enabled = false;
tsbBuscar.Enabled = false;
txtNome.Enabled = true;
txtEndereco.Enabled = true;
mskCep.Enabled = true;
txtBairro.Enabled = true;
txtCidade.Enabled = true;
txtUf.Enabled = true;
mskTelefone.Enabled = true;
txtNome.Focus();
novo = true;
}
Pode-se notar que na última linha de código está sendo atribuído true para a variável novo. Mais adiante será possível entender melhor que isso significa que ao clicar no botão Novo será incluído um novo registro.
A Listagem 5 contém com o código do botão Salvar.
private void tsbSalvar_Click(object sender, EventArgs e)
{
if (novo)
{
string sql = "INSERT INTO CLIENTE
(NOME,ENDERECO,CEP,BAIRRO,CIDADE,UF,TELEFONE) "
+ "VALUES ('" + txtNome.Text + "', '" + txtEndereco.Text + "', '"
+ mskCep.Text + "', '" + txtBairro.Text
+ "', '" + txtCidade.Text + "', '" + txtUf.Text + "', '"
+ mskTelefone.Text + "')";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.Text;
con.Open();
try
{
int i = cmd.ExecuteNonQuery();
if (i > 0)
MessageBox.Show("Cadastro realizado com sucesso!");
}
catch (Exception ex)
{
MessageBox.Show("Erro: " + ex.ToString());
}
finally
{
con.Close();
}
}
else
{
string sql = "UPDATE CLIENTE SET NOME='" + txtNome.Text + "',
ENDERECO='" + txtEndereco.Text + "', " +
"CEP='" + mskCep.Text + "', BAIRRO='" + txtBairro.Text + "',
CIDADE='" + txtCidade.Text + "', " +
"UF='" + txtUf.Text + "', TELEFONE='" + mskTelefone.Text + "'
WHERE ID=" + txtId.Text";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.Text;
con.Open();
try
{
int i = cmd.ExecuteNonQuery();
if (i > 0)
MessageBox.Show("Cadastro atualizado com sucesso!");
}
catch (Exception ex)
{
MessageBox.Show("Erro: " + ex.ToString());
}
finally
{
con.Close();
}
}
tsbNovo.Enabled = true;
tsbSalvar.Enabled = false;
tsbCancelar.Enabled = false;
tsbExcluir.Enabled = false;
tstId.Enabled = true;
tsbBuscar.Enabled = true;
txtNome.Enabled = false;
txtEndereco.Enabled = false;
mskCep.Enabled = false;
txtBairro.Enabled = false;
txtCidade.Enabled = false;
txtUf.Enabled = false;
mskTelefone.Enabled = false;
txtId.Text = "";
txtNome.Text = "";
txtEndereco.Text = "";
mskCep.Text = "";
txtBairro.Text = "";
txtCidade.Text = "";
txtUf.Text = "";
mskTelefone.Text = "";
}
Neste código há um if que testa o valor da variável novo para saber se é um registro novo e executa o código.
Quando novo=true, a variável SQL (que é uma string) recebe uma instrução SQL de INSERT que está sendo montada com os valores dos campos.
Logo após é criado um objeto com do tipo SqlConnection que é a conexão com o banco e que recebe como parâmetro no momento da instanciação a variável connectionString que foi criada anteriormente e que contém a string de conexão.
Depois é criado o objeto cmd que é um SqlCommand que recebe como parâmetro no seu construtor a variável SQL que contém a instrução SQL e o objeto con que é a conexão.
O objeto cmd será responsável por executar a instrução SQL.
Depois é definido o tipo de comando do objeto cmd, no caso Text, logo em seguida é aberta a conexão.
Dentro do bloco try é executada a instrução SQL do objeto cmd através do método ExecuteNonQuery que retorna o número de linha afetadas, que no caso é armazenada na variável inteira i.
Logo após testa-se se o valor de i é maior que 0, se sim significa que o registro foi incluído com sucesso.
Voltando um pouco, se quando o if testa a variável novo e ela for false então executa o código contido no bloco else que significa que está fazendo uma atualização de um registro.
O código é praticamente o mesmo, a não ser a instrução SQL que agora é um UPDATE.
Logo depois é alterado o estado dos controles do formulário novamente.
A Listagem 6 contém o código do botão Cancelar, que só alterada o estado dos controles e limpa os TextBox’s.
private void tsbCancelar_Click(object sender, EventArgs e)
{
tsbNovo.Enabled = true;
tsbSalvar.Enabled = false;
tsbCancelar.Enabled = false;
tsbExcluir.Enabled = false;
tstId.Enabled = true;
tsbBuscar.Enabled = true;
txtNome.Enabled = false;
txtEndereco.Enabled = false;
mskCep.Enabled = false;
txtBairro.Enabled = false;
txtCidade.Enabled = false;
txtUf.Enabled = false;
mskTelefone.Enabled = false;
txtId.Text = "";
txtNome.Text = "";
txtEndereco.Text = "";
mskCep.Text = "";
txtBairro.Text = "";
txtCidade.Text = "";
txtUf.Text = "";
mskTelefone.Text = "";
}
A Listagem 7 mostra o código do botão Excluir, que é bem parecido ao do botão Salvar, só que agora com a instrução de DELETE.
private void tsbExcluir_Click(object sender, EventArgs e)
{
string sql = "DELETE FROM CLIENTE WHERE ID=" + txtId.Text;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.Text;
con.Open();
try
{
int i = cmd.ExecuteNonQuery();
if (i > 0)
MessageBox.Show("Registro excluído com sucesso!");
}
catch (Exception ex)
{
MessageBox.Show("Erro: " + ex.ToString());
}
finally
{
con.Close();
}
tsbNovo.Enabled = true;
tsbSalvar.Enabled = false;
tsbCancelar.Enabled = false;
tsbExcluir.Enabled = false;
tstId.Enabled = true;
tsbBuscar.Enabled = true;
txtNome.Enabled = false;
txtEndereco.Enabled = false;
mskCep.Enabled = false;
txtBairro.Enabled = false;
txtCidade.Enabled = false;
txtUf.Enabled = false;
mskTelefone.Enabled = false;
txtId.Text = "";
txtNome.Text = "";
txtEndereco.Text = "";
mskCep.Text = "";
txtBairro.Text = "";
txtCidade.Text = "";
txtUf.Text = "";
mskTelefone.Text = "";
}
A Listagem 8 mostra o código do botão Buscar.
private void tsbBuscar_Click(object sender, EventArgs e)
{
string sql = "SELECT * FROM CLIENTE WHERE ID=" + tstId.Text;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.Text;
SqlDataReader reader;
con.Open();
try
{
reader = cmd.ExecuteReader();
if (reader.Read())
{
tsbNovo.Enabled = false;
tsbSalvar.Enabled = true;
tsbCancelar.Enabled = true;
tsbExcluir.Enabled = true;
tstId.Enabled = false;
tsbBuscar.Enabled = false;
txtNome.Enabled = true;
txtEndereco.Enabled = true;
mskCep.Enabled = true;
txtBairro.Enabled = true;
txtCidade.Enabled = true;
txtUf.Enabled = true;
mskTelefone.Enabled = true;
txtNome.Focus();
txtId.Text = reader[0].ToString();
txtNome.Text = reader[1].ToString();
txtEndereco.Text = reader[2].ToString();
mskCep.Text = reader[3].ToString();
txtBairro.Text = reader[4].ToString();
txtCidade.Text = reader[5].ToString();
txtUf.Text = reader[6].ToString();
mskTelefone.Text = reader[7].ToString();
novo = false;
}
else
MessageBox.Show("Nenhum registro encontrado com o Id
informado!");
}
catch (Exception ex)
{
MessageBox.Show("Erro: " + ex.ToString());
}
finally
{
con.Close();
}
tstId.Text = "";
}
No código do botão Buscar contém uma instrução de SELECT que retorna o registro com o Id informado.
Uma diferença é que além do objeto cmd agora também um objeto reader do tipo SqlDataReader que armazena o conteúdo retornado da consulta, como é mostrado na Listagem 9.
reader = cmd.ExecuteReader();
Em seguida, o if testa se há registro no reader com o método Read. Se sim, executa-se o bloco.
O que há de diferente é que logo após alterar os estados dos controles o foco do cursor é posicionado no campo txtNome através do método Focus e é atribuído a cada campo o valor correspondente que está no reader.
Para acessar os campos no reader é utilizado o índice do campo. Esse índice é a ordem dos campos, para poder vê-los basta executar um SELECT no SQL Server Management Studio e ver o retorno, o primeiro campo inicia no índice 0.
Pronto, o CRUD está pronto, basta agora executar o programa e testar.
Como dito no início do artigo, existem maneiras melhores de fazer esse CRUD, mais o intuito foi fazê-lo da maneira mais simples para um fácil entendimento.
Saiu na DevMedia!
- Conhecendo os recursos do Visual Studio: O Visual Studio é um ambiente de desenvolvimento integrado (IDE) onde podemos criar aplicações e bibliotecas com muitos frameworks e linguagens diferentes.
Saiba mais sobre PHP ;)
- Guias de .NET: Aqui você encontra todos os Guias de estudo que você irá precisar para dominar por completo a linguagem .NET e todos seus recursos. Escolha o seu!
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo