Introdução
Neste artigo irei abordar um dos
tópicos mais usados no desenvolvimento de softwares, que é o acesso a dados.
Vou ilustrar o conceito de banco, entidades, relacionamento entre entidades e o
famoso CRUD (Create, Read, Update e Delete), que para nós brasileiros é o
criar, ler, atualizar e excluir dados.
Quando falamos em banco de dados
pensamos num conjunto de informações armazenadas em algum repositório, de forma
que se possam manipular tais informações. O mais conhecido da Microsoft é o SQL
Server, e no artigo faremos acesso a ele.
Outro ponto importante de comentar é
que o acesso a dados será feito usando o ADO.NET e suas classes, ou seja, será
direto nas entidades, não irei usar nenhuma tecnologia de modelagem de objeto
relacional, como por exemplo, o fantástico Entity Framework 4.
O que é um banco de
dados?
Costumo definir que banco de dados é
um repositório de informações organizadas. No SQL Server organizamos estas
informações de forma relacional, permitindo fazer consultas envolvendo diversas
entidades.
O que é uma
entidade?
Entidade é o local onde as
informações relacionadas a um conjunto são armazenadas. Por exemplo, se
pensarmos em uma entidade de pessoas, teremos todas as informações sobre a
pessoa como nome, e-mail, telefone, endereço, etc.
No entanto é comum ter diversas
entidades no banco. Algumas aplicações grandes de ERP chegam a ter cerca de 600
entidades.
E como que uma entidade se relaciona
a outra? Em primeiro lugar, sim, é possível relacionar diversas entidades entre
si. Segundo, o tipo de relacionamento define a maneira que serão armazenados os
dados. Temos os seguintes tipos:
- Um para Muitos – um registro na
entidade A contém diversos registros na entidade B. Por exemplo, um cliente de
vários pedidos, um clube tem diversos jogadores.
- Um para Um – um registro na
entidade A contém apenas um registro na entidade B. Por exemplo, um cliente na
entidade A contém as informações sobre aspectos comerciais na entidade B e
também informações sobre informações de créditos na entidade C.
- Muitos para Muitos – o mesmo
registro pode estar relacionado várias vezes nas entidades A e B. Por exemplo,
uma mulher pode ter diversos homens, e um homem pode ter diversas mulheres.
Tipos de Campos
Todo banco de dados dispõe os tipos
de campos para informações específicas. Isto tudo para facilitar o uso, acesso,
conversões na programação, compartilhamento com outros bancos e aplicações.
Veja alguns tipos de dados: string (texto), integer (inteiro), double (duplo),
money (monetário), data (data), dateTime (data e hora), binário, image
(imagem). Claro que cada tipo de banco de dados tem tipos diferentes, mas em
linhas gerais estes são os mais comuns.
Ler Dados do Banco
Vamos aos códigos.
Primeiramente utilizarei o banco de dados northwind, que é o mais conhecido no
mundo, o qual você pode fazer download no linkhttp://northwinddatabase.codeplex.com/ e instalar
no SQL Server.
Na programação o primeiro passo
definir a string de conexão, sendo necessário definir o Data Source (servidor),
o Initial Catalog (nome do banco de dados), Integrated Security (segurança
integrada), user id (usuário) e password (senha). Claro que cada string de
conexão depende de onde está instalado e os dados podem ser diferentes.
Por exemplo, a linha a seguir
representa a string de conexão na minha máquina, o qual MARTE é o nome da minha
máquina (pode ser o número IP, . (ponto) ou localhost). O nome do banco é o
Northwind e uso segurança integrada.
string conexao = "Data Source=NomeDoServe;Initial
Catalog=Northwind;Integrated Security=True";
Como usarei o SQL
Server, é preciso declarar o namespace a ser usado que contém todos os métodos
e propriedades da classe de acesso a dados. Portanto, o código a seguir deverá
ser declarado na lista de using.
using System.Data.SqlClient;
Em seguida, no
formulário da aplicação desktop, adicionei um botão e um gridView. O seguinte
código irá ler todos os dados da tabela Produtcs (produtos) e
mostrará no controle dataGridView1.
try
{
string sql = "Select * From
Products";
using (SqlConnection conn = new
SqlConnection(conexao))
{
conn.Open();
DataTable dt = new DataTable();
using
(SqlCommand cmd = new SqlCommand(sql, conn))
{
SqlDataReader reader = cmd.ExecuteReader();
dt.Load(reader);
reader.Close();
}
conn.Close();
dataGridView1.DataSource = dt;
}
}
catch (Exception)
{
MessageBox.Show("Ocorreu algum erro na leitura do banco");
}
Veja a explicação detalhada do
código:
O try / catch controla se houve ou
não o possíveis erros.
try
{
Esta é a instrução
T-SQL (Transact SQL) para ler todos (*) os registros da entidadeProducts.
string sql = "Select * From Products";
Aqui é definido o
objeto SqlConnection responsável em realizar a conexão com o banco de dados
localizado na variável conexao. Em seguida
é feita a abertura da conexão com o Open.
using (SqlConnection conn = new
SqlConnection(conexao))
{
conn.Open();
O objeto DataTable criará uma tabela
na memória, mas será usado logo a seguir.
DataTable dt = new DataTable();
Agora é preciso
executar a consulta no banco, ou seja, o SqlCommand é o
comando que pega a instrução T-SQL definida na variável sql e executa na respectiva conexão definido no objeto conn.
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
Uma vez executado
o SqlCommand, o objeto SqlDataReader irá
efetivamente carregar os dados definidos no comando cmd.
SqlDataReader reader =
cmd.ExecuteReader();
Nesta hora usei o
método Load do DataTable o
qual lê o DataReader declarado emreader. É exatamente
agora que os dados vão pra memória na tabela dt (DataTable).
dt.Load(reader);
Uma vez lidos os
registros, os comandos Close fecham
tanto o DataReader quanto a conexão.
reader.Close();
}
conn.Close();
Como os dados estão
na memória e devem ser mostrados no objeto dataGridView1,
usamos a propriedade DataSource e
atribuímos o dt (DataTable). Pronto, os dados
são mostrados ao usuário.
dataGridView1.DataSource = dt;
}
}
Caso ocorrem algum erro no caminho, é
exibida a mensagem a seguir para o usuário.
catch (Exception)
{
MessageBox.Show("Ocorreu algum erro na leitura do banco");
}
Veja o resultado da execução.
Agora vamos aprender como filtrar
dados, neste caso o usuário irá digitar o valor do preço do produto e o código
irá filtrar todos os produtos onde o preço for maior ou igual. Veja o código completo.
try
{
string sql = "Select * from
Products Where UnitPrice >= @preco";
using (SqlConnection conn = new
SqlConnection(conexao))
{
conn.Open();
DataTable dt = new DataTable();
using
(SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@preco",
Convert.ToDecimal(textBox1.Text));
SqlDataReader reader = cmd.ExecuteReader();
dt.Load(reader);
reader.Close();
}
conn.Close();
dataGridView1.DataSource = dt;
}
}
catch (Exception)
{
MessageBox.Show("Ocorreu algum erro na leitura do banco");
}
Basicamente o
código é igual ao anterior, exceto estas duas linhas. A instrução T-SQL
seleciona todos os produtos onde (Where) o campo UnitPrice (preço) for >= (maior ou igual) ao
@preco. O @preco significa que é um parâmetro, o qual está declarado na linha
seguinte. A sintaxe informa que o comando cmd declara o
parâmetro Parameters e adiciona o
valor AddWithValue declarado no @preco contendo o valor
digitado pelo usuário no controle textBox1. A
propriedade Text lê o valor digitado.
string sql = "Select * from Products Where
UnitPrice >= @preco";
cmd.Parameters.AddWithValue("@preco",
Convert.ToDecimal(textBox1.Text));
Veja o resultado com o filtro 60.
Observe a coluna UnitPrice.
Atualizar Dados no
Banco
Todo banco de dados
pode disponibilizar registros para ser atualizado, isto é comum. Neste exemplo
iremos atualizar o campo UnitsInStock (quantidade
no estoque) igual ao valor que o usuário digitar. No entanto, quando se
atualiza dados é importante destacar para qual registro será realizada a
operação. Neste caso, a quantidade no estoque será atualizada somente para o
produto onde o campo ProductID (código
do produto) for igual ao código que o usuário digitar. Veja o código completo.
try
{
string sql = "Update
Products SET UnitsInStock=@qtde Where ProductID=@codigo";
using (SqlConnection conn = new
SqlConnection(conexao))
{
conn.Open();
using
(SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@qtde",
Convert.ToInt16(txtEstoque.Text));
cmd.Parameters.AddWithValue("@codigo",
Convert.ToInt16(txtID.Text));
cmd.ExecuteNonQuery();
MessageBox.Show("Estoque atualizado");
}
conn.Close();
}
}
catch (Exception)
{
MessageBox.Show("Ocorreu algum erro na atualização de dados");
}
Vamos a explicação
detalhada das linhas que interessam, pois o restante é igual aos códigos vistos
anteriormente. Veja a instrução T-SQL dizendo Update (Atualize)
a tabelaProducts (Produtos) para o campo (SET UnitsInStock) igual ao parâmetro @qtde que é a quantidade que o usuário digitar.
Como a atualização será feita somente para um produto o Where (onde) aplica o filtro com a condição ProductID (código do produto, este é um campo
chave e único) for igual ao parâmetro @codigo cujo
valor o usuário também irá digitar. Nestas instruções de atualização se você
não declarar o filtro (Where) a execução se dará para todos os registros da
entidade, então, preste atenção e aplique o filtro quando necessário.
string sql = "Update Products SET
UnitsInStock=@qtde Where ProductID=@codigo";
Veja a declaração dos dois parâmetros
que o usuário irá digitar as informações nas caixas de texto.
cmd.Parameters.AddWithValue("@qtde",
Convert.ToInt16(txtEstoque.Text));
cmd.Parameters.AddWithValue("@codigo",
Convert.ToInt16(txtID.Text));
Esta linha executa
a operação em si. Toda e qualquer operação que não seja de leitura, use o ExecuteNonQuery para efetivar o comando no banco.
cmd.ExecuteNonQuery();
A seguir vamos aprender como fazer
inclusão de dados no banco de dados. Neste exemplo eu não criei uma interface
de usuário para que ele digite as informações, apenas fixei os dados porque o
foco é mostrar como incluir. O código completo está a
seguir.
try
{
string sql = "INSERT INTO
Products (ProductName, UnitPrice, UnitsInStock, CategoryID) values (@nome,
@preco, @estoque, @categoria)";
using (SqlConnection conn = new
SqlConnection(conexao))
{
conn.Open();
using
(SqlCommand cmd = new SqlCommand(sql, conn))
{
Random rnd = new Random();
int numero = rnd.Next(200, 500);
// valores do produto
cmd.Parameters.AddWithValue("@nome", "Produto" + numero);
cmd.Parameters.AddWithValue("@preco", numero);
cmd.Parameters.AddWithValue("@estoque", numero);
cmd.Parameters.AddWithValue("@categoria", 1);
cmd.ExecuteNonQuery();
MessageBox.Show("Produto cadastrado com sucesso");
button1_Click(null, null);
}
conn.Close();
}
}
catch (Exception)
{
MessageBox.Show("Ocorreu algum erro no cadastro.");
}
Veja como é a
instrução T-SQL para inclusão. Você deve declarar o INSERT INTO(inclua na tabela) Products (Produtos), seguido da lista de campos da
entidade, values(valores) seguido da lista de
parâmetros a serem declarados depois.
string sql = "INSERT INTO Products (ProductName, UnitPrice,
UnitsInStock, CategoryID) values (@nome, @preco, @estoque, @categoria)";
Aqui eu acabei usando um truque, um
artificio para gerar um número aleatório que será usado como dado e exemplo.
Este número aleatório será gerado entre 200 e 500.
Random rnd = new Random();
int numero = rnd.Next(200, 500);
A seguir são declarados todos os
parâmetros para o nome, preço, estoque e categoria do produto novo. Note que
usei o número aleatório gerado para servir como preço, estoque e também no nome
do produto, o qual concatenei com a palavra Produto gerando por exemplo
Produto234, Produto123, etc.
// valores do produto
cmd.Parameters.AddWithValue("@nome",
"Produto" + numero);
cmd.Parameters.AddWithValue("@preco",
numero);
cmd.Parameters.AddWithValue("@estoque",
numero);
cmd.Parameters.AddWithValue("@categoria",
1);
cmd.ExecuteNonQuery();
0 comentários:
Postar um comentário