Sei sulla pagina 1di 18

Banco de Dados

Renato Haddad

Microsoft Most Valuable Professional MVP, MCT, MCPD e MCTS

Tecnologias

Visual Studio .NET 2010, C#

Introduo

Neste artigo irei abordar um dos tpicos 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 ns brasileiros o criar, ler, atualizar e excluir dados.

Quando falamos em banco de dados pensamos num conjunto de informaes armazenadas em algum repositrio, de forma que se possam manipular tais informaes. 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, no irei usar nenhuma tecnologia de modelagem de objeto relacional, como por exemplo, o fantstico Entity Framework 4.

O que um banco de dados?

Costumo definir que banco de dados um repositrio de informaes organizadas. No SQL Server organizamos estas informaes de forma relacional, permitindo fazer consultas envolvendo diversas entidades.

O que uma entidade?

Entidade o local onde as informaes relacionadas a um conjunto so armazenadas. Por exemplo, se pensarmos em uma entidade de pessoas, teremos todas as informaes sobre a pessoa como nome, e-mail, telefone, endereo, etc.

No entanto comum ter diversas entidades no banco. Algumas aplicaes grandes de ERP chegam a ter cerca de 600 entidades.

E como que uma entidade se relaciona a outra? Em primeiro lugar, sim, possvel relacionar diversas entidades entre si. Segundo, o tipo de relacionamento define a maneira que sero armazenados os dados. Temos os seguintes tipos:

- Um para Muitos um registro na entidade A contm diversos registros na entidade B. Por exemplo, um cliente de vrios pedidos, um clube tem diversos jogadores.

- Um para Um um registro na entidade A contm apenas um registro na entidade B. Por exemplo, um cliente na entidade A contm as informaes sobre aspectos comerciais na entidade B e tambm informaes sobre informaes de crditos na entidade C.

- Muitos para Muitos o mesmo registro pode estar relacionado vrias 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 dispe os tipos de campos para informaes especficas. Isto tudo para facilitar o uso, acesso, converses na programao, compartilhamento com outros bancos e aplicaes. Veja alguns tipos de dados: string (texto), integer (inteiro), double (duplo), money (monetrio), data (data), dateTime (data e hora), binrio, image (imagem). Claro que cada tipo de banco de dados tem tipos diferentes, mas em linhas gerais estes so os mais comuns.

Ler Dados do Banco

Vamos aos cdigos. Primeiramente utilizarei o banco de dados northwind, que o mais conhecido no mundo, o qual voc pode fazer download no link http://northwinddatabase.codeplex.com/ e instalar no SQL Server.

Na programao o primeiro passo definir a string de conexo, sendo necessrio definir o Data Source (servidor), o Initial Catalog (nome do banco de dados), Integrated Security (segurana integrada), user id (usurio) e password (senha). Claro que cada string de conexo depende de onde est instalado e os dados podem ser diferentes.

Por exemplo, a linha a seguir representa a string de conexo na minha mquina, o qual MARTE o nome da minha mquina (pode ser o nmero IP, . (ponto) ou localhost). O nome do banco o Northwind e uso segurana integrada.

string conexao = "Data Source=MARTE;Initial Catalog=Northwind;Integrated Security=True";

Como usarei o SQL Server, preciso declarar o namespace a ser usado que contm todos os mtodos e propriedades da classe de acesso a dados. Portanto, o cdigo a seguir dever ser declarado na lista de using.

using System.Data.SqlClient;

Em seguida, no formulrio da aplicao desktop, adicionei um boto e um gridView. O seguinte cdigo 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 explicao detalhada do cdigo:

O try / catch controla se houve ou no o possveis erros.

try

Esta a instruo T-SQL (Transact SQL) para ler todos (*) os registros da entidade Products.

string sql = "Select * From Products";

Aqui definido o objeto SqlConnection responsvel em realizar a conexo com o banco de dados localizado na varivel conexao. Em seguida feita a abertura da conexo com o Open.

using (SqlConnection conn = new SqlConnection(conexao))

conn.Open();

O objeto DataTable criar uma tabela na memria, 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 instruo T-SQL definida na varivel sql e executa na respectiva conexo 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 mtodo Load do DataTable o qual l o DataReader declarado em reader. exatamente agora que os dados vo pra memria na tabela dt (DataTable).

dt.Load(reader);

Uma vez lidos os registros, os comandos Close fecham tanto o DataReader quanto a conexo.

reader.Close();

conn.Close();

Como os dados esto na memria e devem ser mostrados no objeto dataGridView1, usamos a propriedade DataSource e atribumos o dt (DataTable). Pronto, os dados so mostrados ao usurio.

dataGridView1.DataSource = dt;

Caso ocorrem algum erro no caminho, exibida a mensagem a seguir para o usurio.

catch (Exception)

MessageBox.Show("Ocorreu algum erro na leitura do banco");

Veja o resultado da execuo.

Agora vamos aprender como filtrar dados, neste caso o usurio ir digitar o valor do preo do produto e o cdigo ir filtrar todos os produtos onde o preo for maior ou igual. Veja o cdigo 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 cdigo igual ao anterior, exceto estas duas linhas. A instruo T-SQL seleciona todos os produtos onde (Where) o campo UnitPrice (preo) for >= (maior ou igual) ao @preco. O @preco significa que um parmetro, o qual est declarado na linha seguinte. A sintaxe informa que o comando cmd declara o parmetro Parameters e adiciona o valor AddWithValue declarado no @preco contendo o valor digitado pelo usurio 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 usurio digitar. No entanto, quando se atualiza dados importante destacar para qual registro ser realizada a operao. Neste caso, a quantidade no estoque ser atualizada somente para o produto onde o campo ProductID (cdigo do produto) for igual ao cdigo que o usurio digitar. Veja o cdigo 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 atualizao de dados");

Vamos a explicao detalhada das linhas que interessam, pois o restante igual aos cdigos vistos anteriormente. Veja a instruo T-SQL dizendo Update (Atualize) a tabela Products (Produtos) para o campo (SET UnitsInStock) igual ao parmetro @qtde que a quantidade que o usurio digitar. Como a atualizao ser feita somente para um produto o Where (onde) aplica o filtro com a condio ProductID (cdigo do produto, este um campo chave e nico) for igual ao parmetro @codigo cujo valor o usurio tambm ir digitar. Nestas instrues de atualizao se voc no declarar o filtro (Where) a execuo se dar para todos os registros da entidade, ento, preste ateno e aplique o filtro quando necessrio.

string sql = "Update Products SET UnitsInStock=@qtde Where ProductID=@codigo";

Veja a declarao dos dois parmetros que o usurio ir digitar as informaes nas caixas de texto.

cmd.Parameters.AddWithValue("@qtde",

Convert.ToInt16(txtEstoque.Text));

cmd.Parameters.AddWithValue("@codigo",

Convert.ToInt16(txtID.Text));

Esta linha executa a operao em si. Toda e qualquer operao que no seja de leitura, use o ExecuteNonQuery para efetivar o comando no banco.

cmd.ExecuteNonQuery();

A seguir vamos aprender como fazer incluso de dados no banco de dados. Neste exemplo eu no criei uma interface de usurio para que ele digite as informaes, apenas fixei os dados porque o foco mostrar como incluir. O cdigo 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 instruo T-SQL para incluso. Voc deve declarar o INSERT INTO (inclua na tabela) Products (Produtos), seguido da lista de campos da entidade, values (valores) seguido da lista de parmetros 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 nmero aleatrio que ser usado como dado e exemplo. Este nmero aleatrio ser gerado entre 200 e 500.

Random rnd = new Random();

int numero = rnd.Next(200, 500);

A seguir so declarados todos os parmetros para o nome, preo, estoque e categoria do produto novo. Note que usei o nmero aleatrio gerado para servir como preo, estoque e tambm 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();

Veja um exemplo de dois novos produtos cadastrados.