The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ......

32
março 2010

Transcript of The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ......

Page 1: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010

Page 2: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010

Page 3: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 03

Banco de Dados

Stored Procedures e Triggers no MySQL

19Autor: Bruno Alcarás

Desafio The Club

.NET

- Dicas Delphi

28Dicas

- Cruzada

30

Delphi

Banco de Dados

índiceUtilizando componentes ABCr no Delphi 2010

Editorial Delphi

10Espero que nesse mês todos tenham recebido muitos ovinhos do coelhinho. Quem não recebeu seja um bom menino...04

Manipulando Streams no Delphi 2010

05Indo mais além eplorando as tabelas de sistema Interbase/Firebird 14

Novidades do Visual Studio 2010

24

LegendaInicianteIntermediárioAvançado

Autor: Antonio Spitaleri

Autor: Felipe SantosAutor: Djonatas Tenfen

Autor: Antonio Spitaleri

Page 4: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201004

Bem-vindo

Delphi é marca registrada da Borland International, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Marcos César Silva - Editor [email protected]

Espero que nesse mês todos tenham recebido muitos ovinhos do coelhinho. Quem não recebeu seja um bom menino ou menina que no próximo ano ele vem.

Aproveito para convidar nossos leitores a comparecerem ao “Microsoft TechDay” que será realizado em Blumenau-SP no dia 24/04 e que tem com um dos idealizadores nosso colunista Djonatas Tenfen. O The Club tem prazer em apoiar essa iniciativa. Tenho certeza que será um grande evento. Saiba mais acessando: www.mstechday.com

Nessa edição temos artigos pra todos os gostos.

Nosso consultor técnico Antonio Spitaleri Neto trabalha dobrado esse mês e nos apresenta dois artigos. No primeiro, ”Manipulando Streams no Delphi 2010”, ele fala sobre um recurso presente no Delphi desde o seu início, os Streams, e que apesar de ser pouco utilizado nos dias de hoje, pode ser muito importante para alguns pontos específicos dos nossos aplicativos. No segundo, ”Utilizando os Componente ACBr com Impressoras Fiscais no Delphi 2010” ele fala sobre os componentes Open Source ACBr que são uma verdadeira “mão na roda” para nós desenvolvedores trabalharmos com ECF.

Iniciando as páginas dedicadas a Banco de Dados dessa edição, Felipe Santos com seu artigo “Indo mais além, explorando as tabelas de sistema Interbase/Firebird” nos mostra como trabalhar com as tabelas de sistema do Interbase/Firebird visando uma melhor manutenção dos nossos Bancos de Dados.

Nosso consultor Jr. Bruno Alcarás neste mês nos trás o artigo “Stored Procedure e Triggers no MySQL”, nos dando uma visão geral sobre esses ótimos recursos que são mais conhecidos em Banco de Dados Firebird mas que também tem um papel muito importante no desenvolvimento de um Banco MySQL.

Djonatas Tenfen no seu artigo “Novidades do Visual Studio 2010” nos apresenta as principais novidades dessa nova versão do Visual Studio que foi oficialmente lançado no dia 12/04.

Um grande abraço

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações: (14) 3732-1529 Suporte: (14) 3733-1588

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club Megazine 2009

Diretor TécnicoMarcos César Silva

Diagramação e ArteVitor M. Rodrigues

RevisãoTassiane Fileto

ColunistasAntonio Spitaleri Neto

Bruno AlcarásDjonatas TenfenFelipe Santos

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

Page 5: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 05

Delphi

Entre os vários recursos que existem desde versões mais antigas do Delphi e ainda assim são pouco explorados pelos desen-volvedores especializados na ferramenta, sem dúvida um dos mais destacados são os Streams. Streams são objetos que remetem ao início dos tempos da programação, quando a manipulação de dados era feita byte a byte. Com o surgimento de novas tecnologias, a uti-lização dos Streams ficou restrita a situações em que os mesmos são imprescindíveis.

No Delphi existe uma classe base TStre-am e dela descendem as demais classes de manipulação de Streams: TMemoryStream, TFileStream, TBlobStream. Essas três classes que citei são as mais importantes na mani-pulação de Streams em Delphi. Apesar de possuírem diferenças entre si, a forma de trabalhar com cada uma das três classes é bem semelhante.

Manipulando Streams no Delphi 2010

Nesse artigo estarei abordando de forma prática o uso dos Streams utilizando a versão 2010 do Delphi. Porém os exemplos funcio-nam em versões anteriores do Delphi com pouca ou nenhuma modificação.

Mãos a obra!

FileStream

Como o próprio nome já sugere, a classe TFileS-tream, descendente de TStream, manipula arquivos em disco na forma de Streams. Em geral utilizamos essa forma de Stream para manipular arquivos de texto, mas a utilização da mesma para outros tipos de arquivos é perfeitamente possível.

Inicie uma nova aplicação no Delphi e monte o layout da mesma conforme a figura 1:

Figura 1

Page 6: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010

O que faremos a seguir é carregar um arquivo texto para um objeto FileStream e em seguida car-regar esse Stream no objeto Memo para exibição do mesmo.

Quando criamos um objeto FileStream no construtor do mesmo temos de informar além do caminho do arquivo o modo de abertura desse arquivo. FileStream nos possibilita quatro formas de abertura que são:

Fmcreate- Caso o arquivo não exista, será criado. Caso exista, será zerado e a escrita no mesmo irá sobrescrever seu conteúdo atual;

Fmopenread- Abre o arquivo apenas para leitura;

Fmopenwrite- Abre o arquivo apenas para escrita;

Fmopenreadwrite- Abre o arquivo para leitura e escrita.

O primeiro passo será a busca do arquivo com o OpenDialog, que será feita no evento OnClick do botão “Carregar”.

Segue o código:

procedure TForm1.

btncarregarClick(Sender:

TObject);

var

sFilename:string;

begin

if(OpenDialog1.Execute)

then

sFilename:=OpenDialog1.

FileName;

edtcaminho.

Text:=sFilename;

end;

Com o caminho do arquivo devidamente sele-

cionado, iremos realizar a carga do mesmo para o FileStream e exibir o conteúdo do mesmo no objeto memo que inserimos na aplicação.

Segue o código:

procedure TForm1.

btnexibirClick(Sender:

TObject);

var

sFilename:string;

oFileStream:TFileStream;

begin

try

sFilename:=edtcaminho.

Text;

oFileStream:=TFileStream.

Create(sFilename,fmOpenRead);

memstream.Lines.

LoadFromStream(oFileStream);

finally

FreeAndNil(oFileStream);

end;

end;

Salve as alterações e teste o aplicativo. Se tudo correu bem, o resultado será semelhante ao mostrado na figura 2:

Veja a Figura 2.

Stream com imagens

Embora não seja o mais recomendado, todos os servidores de banco de dados utilizados com o Delphi aceitam o armazenamento de dados na forma binária através de campos Blob. Esse tipo de campo em geral é utilizado para o armazenamento de imagens no banco de dados, mas pode ser uti-lizado para armazenar vídeos, textos entre outros dados de forma binária.

Para se trabalhar com campos Blob nos com-ponentes DataSet existentes no Delphi, podemos lançar mão de mais duas classes: TBlobStream, para os componentes BDE, e TMemorystream ou a própria classe TStream para demais tipos de DataSets. Com essas classes poderão ser feitos o envio e recuperação de dados a partir de campos Blob. Lembrando que para o Stream independe se o campo Blob contém um texto, uma imagem ou outra forma de dado. Sua função é apenas servir de veículo para envio e recuperação dessas informações.

Vamos a um exemplo prático com Blob em combinação com outros dois objetos para carga de imagens. No PageControl de nossa aplicação, adicione uma nova página e coloque como caption da mesma “Blobstream”. Em seguida adicione a página um componente Clientdataset, alterando seu nome para CdsBlob. Abra o FieldsEditor do

Figura 2

Page 7: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 07

clientdataset e adicione campo Blob com o nome de IMAGEM. Isso feito clique com o botão direito sobre o clientdataset e clique em CreateDataSet.

Nesse exemplo estarei trabalhando com o clientdataset apenas em memória, mas ele poderia estar ligado a uma fonte de dados sem problemas.

Com o clientdataset devidamente criado e configurado, monte o restante do layout da página conforme a figura 3.

Os outros dois objetos que estaremos utilizan-do são: TStream para a recuperação do conteúdo do Blob após o mesmo ter sido carregado. E TJpe-gImage para armazenar a imagem proveniente do campo Blob.

Veja a Figura 3.

Lembrando que o componente OpenDialog não precisa ser criado novamente, será utilizado o que já havíamos criado na primeira página.

Iremos selecionar o caminho de uma imagem para em seguida enviá-lo para o Blobstream. Para a seleção do arquivo, no evento OnClick do botão “Selecionar” faça:

procedure TForm1.

SelecionarClick(Sender:

TObject);

begin

OpenDialog1.

Filter:=EmptyStr;

OpenDialog1.

Filter:=’Image Files|*.

jpg’;

if(OpenDialog1.Execute)

then

edtcaminhoimg.

Text:=OpenDialog1.

FileName;

end;

Alteramos o filtro do OpenDialog para que apenas aceite imagens com a extensão jpeg e em

Figura 3

procedure TForm1.SalvarClick(Sender: TObject);var sFilename:string; oFilestream:TFileStream; oMemorystream:TStream; oImage:TJPEGImage;begin try sFilename:=edtcaminhoimg.Text; oFilestream:=TFileStream.Create(sFilename,fmOpenRead); oMemorystream:=TMemoryStream.Create; oImage:=TJPEGImage.Create; cdsblob.Open; cdsblob.Append; cdsblobIMAGEM.LoadFromStream(oFilestream); cdsblob.Post; oMemorystream:=cdsblob.CreateBlobStream(cdsblobIMAGEM,bmRead); oImage.LoadFromStream(oMemorystream); Image1.Picture.Assign(oImage); finally FreeAndNil(oFilestream); FreeAndNil(oMemorystream); FreeAndNil(oImage); end;

Listagem 4

seguida salvamos o caminho do arquivo de imagem na Edit edtcaminho.

Como estamos trabalhando com imagens em formato Jpeg devemos adicionar na uses da unit a biblioteca Jpeg.

Iremos agora salvar essa imagem já selecio-

nada em um FileStream, salvá-la no campo blob e depois recuperá-la com a técnica do blobstream combinada com o Jpegimage.

Veja a codificação no evento OnClick do botão “Salvar”:

Veja a listagem 4.

Page 8: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201008

Figura 5

Botão “Selecionar Arquivo”:

procedure TForm1.btnarqselecionarClick(Sender:

TObject);

begin

if(OpenDialog1.Execute)then

edtcaminhoarq.Text:=OpenDialog1.FileName;

end;

Botão “Copiar”:

procedure TForm1.btncopiarClick(Sender: TObject);

var

oStreamin,

oStreamout:TFileStream;

aBufferstream:array[0..1023]of Byte;

Figura 4

Repare que o objeto TJpegImage apenas serve de container provisório para receber a imagem proveniente do campo Blob.

Com essa técnica podemos salvar e recuperar imagens em qualquer DataSet que ofereça suporte aos campos Blob.

Salve as alterações e teste o aplicativo. Um exemplo de resultado pode ser visto na figura 4:

Veja a Figura 4.

Trabalhando com buffers

Quando trabalhamos com Streams é impor-tante termos em mente que o conteúdo do Stream irá ocupar uma certa quantidade de memória no computador. Em algumas situações pode ser im-portante que tenhamos um controle mais preciso desse espaço e de como ele será manipulado. Esse maior controle pode ser conseguido com a técnica de “bufferização”, que consiste em alocar previamente um espaço de memória onde o buffer irá trabalhar. Algo semelhante ao que é feio com ponteiros em linguagens como C++.

Antes de passarmos a prática com buffers, é importante destacar duas propriedades importan-tes de um Stream, que são: Size e Position.

Size retorna um inteiro com o tamanho ocu-pado pelo Stream, e Position também retorna um inteiro com a posição atual do cursor de leitura do Stream. Assim como os datasets, Streams também possuem um cursor interno responsável pela leitura dos dados.

Vamos a prática. Adicione uma nova página ao PageControl da aplicação e monte seu layout conforme a figura 5:

Veja a Figura 5.

Nesse exemplo iremos selecionar um arquivo texto, carregá-lo para um FileStream, em seguida copiá-lo para outro FileStream com a técnica da bufferização e exibir seu conteúdo no Memo.

Page 9: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 09

Consultor Técnico The Club.

Sobre o autor

Antonio Spitaleri Neto

[email protected]

Figura 6

Veja o aplicativo em execução na Figura 6:

Veja a Figura 6.

Conclusão

Streams são um excelente recurso disponibi-lizado pelo Delphi quando necessitamos utilizar técnicas avançadas de manipulação de arquivos em disco sendo carregados em memória.

Espero que tenham gostado e até a próxima!

iByteRead:integer;

sFilename:string;

begin

try

ProgressBar1.Position:=0;

sFilename:=edtcaminhoarq.Text;

oStreamin:=TFileStream.

Create(sFilename,fmOpenRead);

oStreamout:=TFileStream.Create(‘temp.

txt’,fmCreate);

repeat

iByteRead:=oStreamin.

Read(aBufferstream,1024);

oStreamout.Write(abufferstream,iByteRead);

ProgressBar1.StepBy(1);

until(iByteRead=0);

finally

ProgressBar1.Position:=100;

FreeAndNil(oStreamin);

FreeAndNil(oStreamout);

Memo1.Lines.LoadFromFile(‘temp.txt’);

end;

end;

Page 10: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201010

No dia-a-dia do desenvolvimento voltado para a área de automação comercial, uma grande preocupação dos desenvolvedores é a comunicação do aplicativo com as cha-madas impressoras fiscais, conhecidas pela sigla “ECF”. Para quem trabalha nesse ramo a algum tempo, a solução mais simples e co-mumente utilizada eram as dll’s dos próprios desenvolvedores da ECF utilizada.

Recorrer a essas dll’s sem dúvida torna o trabalho de se comunicar com as ECF’s mais tranqüilo, porém apresenta um incoveniente: E se o modelo e\ou fabricante da ECF for trocada pelo cliente? Ou ainda se um cliente novo utilizar um modelo de um fabricante diferente? Para essas situações, se faz ne-cessário readaptar o aplicativo para trabalhar com o novo modelo\fabricante de ECF.

O projeto ACBr vem de encontro a esse problema. Esse conjunto de componentes e rotinas totalmente Open Source e desenvol-vido em Delphi, permite que a aplicação que irá se comunicar com a ECF seja desenvolvida apenas uma vez, e a troca de modelo ou fabricante de componente deixa de ser um problema.

Utilizando os componentes ACBr com Impressoras

Fiscais no Delphi 2010

Outro ponto importante a se destacar no Acbr é o fato de utilizar muitos dos conceitos da orientação a objetos. Conceitos esses muito raramente utilizados quando se trata de aplicativos e bibliotecas desenvolvidos em Delphi. O fato de utilizar orientação a objetos tornou o código do ACBr mais legível e extensível e ao longo dos últimos anos várias melhorias tem sido aplicadas ao projeto.

Nesse artigo, estarei mostrando como podemos utilizar o ACBr para fazermos nosso aplicativo se comunicar com uma impresso-ra fiscal. Para os que não dispõem de uma impressora fiscal para testes, é importante ressaltar que o exemplo funciona com emu-ladores de ECF sem problemas.

No artigo não estarei mostrando a insta-lação dos componentes ACBr no Delphi 2010, já que instruções para instalação acompa-nham o componente.

Também não será abordada no artigo a instalação e configuração de emuladores de ECF.

Iniciando a aplicação

Criaremos uma aplicação que irá realizar as principais operações relacionadas às impressoras fiscais, como por exemplo: Leitura X, Redução Z, além é claro das operações de registro de itens em uma venda.

Veja como ficará o layout principal da aplicação na figura 1:

No alto e a esquerda da tela, temos dois componentes ComboBox onde no primeiro iremos colocar na propriedade Items uma lista com os modelos suportados pelo Acbr. São eles:

ecfNenhum, ecfNaoFiscal, ecfBematech, ecfSweda, ecfDaruma, ecfSchalter,

ecfMecaf, ecfYanco, ecfDataRegis, ecfUrano, ecfICash, ecfQuattro, ecfFiscNET, ecfEpson, ecfNCR, ecfSwedaSTX;

No segundo componente ComboBox, coloca-remos uma lista com os nomes das portas COM disponíveis no computador. No exemplo fiz a lista com as portas COM1 até COM6.

Logo abaixo dos componentes ComboBox,

Page 11: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 11

Figura 1

temos uma série de 7 botões que utilizaremos para efetuar as operações com a ECF. A função de cada botão pode ser vista nos captions de cada botão.

No lado direito do formulário temos um componente PageControl com duas páginas. Na primeira colocamos um componente TMemo, que será ligado ao componente ACBrEcf através da propriedade MemoBobina deste último. Na segunda página, colocamos um componente TWebbrowser para exibirmos as informações da bobina do ACBrECF.

Finalmente, na parte inferior do formulário, pode ser visto o componente ACBrECF que será o responsável pela interação de nosso aplicativo com a impressora fiscal.

Foi inserido no formulário também um compo-nente StatusBar para exibir o staus da impressora fiscal.

Com o layout da aplicação pronto, iremos criar as rotinas dos botões inseridos no formulário, com execeção do botão “Vender Item” que codificare-mos depois.

Seguem os códigos dos eventos OnClick dos botões:

“Ativar ECF”:

procedure TForm1.btnativarClick(Sender: TObject);begin ACBrECF1.Modelo:=TACBrECFModelo(cmbmodelo.ItemIndex); ACBrECF1.Porta:=cmbporta.Items[cmbporta.ItemIndex]; ACBrECF1.TimeOut:=3000; ACBrECF1.Ativar; Application.ProcessMessages; if ACBrECF1.Ativo then begin btnativar.Enabled:=false; StatusBar1.Panels[0].Text:=’ECF Ativa’; end;end;

“Leitura X”:

procedure TForm1.btnleituraxClick(Sender: TObject);begin ACBrECF1.LeituraX;end;

“Redução Z”:

procedure TForm1.btnreducaozClick(Sender: TObject);begin if(MessageDlg(‘Se for emitida a Redução Z, a ECF ficará inoperante até o dia seguinte.Deseja Continuar?’,mtConfirmation,[mbYes,mbNo],0)=mrYes)then ACBrECF1.ReducaoZ(Now);end;

“Abrir Cupom”:

procedure TForm1.btnabrircupomClick(Sender: TObject);begin ACBrECF1.AbreCupom;

StatusBar1.Panels[0].Text:=’Cupom Aberto’;end;

“Cancela Cupom”:

procedure TForm1.btncancelacupomClick(Sender: TObject);begin ACBrECF1.CancelaCupom; StatusBar1.Panels[0].Text:=’Livre’;end;

“Desativar ECF”:

procedure TForm1.btndesativarClick(Sender: TObject);begin if ACBrECF1.Ativo then ACBrECF1.Desativar; if not ACBrECF1.Ativo then begin btndesativar.Enabled:=false; btnativar.Enabled:=true; end;end;

Page 12: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201012

Destaca-se nesse código a rotina da Redução Z. Como se trata de uma operação que irá deixar a ECF inoperante pelo restante do dia é altamente recomendável que peçamos uma confirmação ao usuário antes de efetuar a mesma.

Em seguida faremos a codificação para exibir os dados da bobina da ECF no WebBrowser. O componente ACBrECF irá enviar os dados para o componente Memo apontado em sua propriedade MemoBobina. O que precisamos fazer é salvar o conteúdo do Memo em um arquivo .html e em seguida exibi-lo no WebBrowser.

Segue o código. Ficará no evento OnChange do componente Memo:

procedure TForm1.membobinaChange(Sender: TObject);begin membobina.Lines.SaveToFile(‘bobina.html’); Application.ProcessMessages;WebBrowser1.Navigate(‘file:///’+ExtractFilePath(Application.ExeName)+’bobina.html’);end;

Repare que com a utilização do componente ACBrECF, todas as operações envolvendo a ECF ficam transparentes ao desenvolvedor. Basta dar um comando através do componente para realizar a operação. Essa sem dúvida é a grande vantagem dessa suíte de componentes.

Teste o aplicativo e salve as alterações. Com isso terminamos a primeira parte de nosso exem-plo. A seguir mostrarei como registrar itens de uma venda através do componente ACBrECF.

Operação de venda de itens

Adicione um novo formulário a aplicação e monte o layout do mesmo conforme mostrado na figura 2:

Veja a Figura 2.

Figura 2

A função que utilizaremos para registrar a venda do item e a função VendeItem do ACBrECF. Essa função recebe os parâmetros necessários para se efetuar uma venda na ECF. Essa função será utilizada no botão “Vender Item”.

Não poderemos permitir a saída da tela sem que a venda seja finalizada. Para isso, no botão “Sair” utilizaremos as funções SubtotalizaCupom e EfetuaPagamento. Essas funções irão encerrar a venda e permitir que a ECF fique livre para uma nova venda.

Referente ao pagamento, é importante ressal-tar que as formas de pagamento precisam estar cadastradas na impressora fiscal. Nesse exemplo, estarei trabalhando com forma de pagamento em dinheiro, representada pelo código 01, constante da maioria das ECF’s.

Antes da codificação nesses botões, volte ao formulário principal e no evento OnClick do botão “Vender Item”, coloque o seguinte código:

procedure TForm1.Button1Click(Sender: TObject);begin try frmvenderitem:=Tfrmvenderitem.Create(Self); frmvenderitem.ShowModal; finally FreeAndNil(frmvenderitem); end;end;

Esse código irá chamar o formulário de venda de itens.

Agora, segue a codificação dos eventos OnClick dos botões do formulário de venda de itens:

Botão “Vender Item” :

procedure Tfrmvenderitem.btnvenderitemClick(Sender: TObject);begin if(Form1.ACBrECF1.Ativo)and(Form1.ACBrECF1.Estado=estVenda)then begin Form1.ACBrECF1.VendeItem(edtcodigo.Text,edtdescricao.Text,edticms.Text, StrToFloat(edtquantidade.Text),StrToFloat(edtvalorunitario.Text), StrToFloat(edtdesconto.Text),edtunidade.Text); end;end;

Botão “Sair”:

procedure Tfrmvenderitem.btnsairClick(Sender: TObject);var sValorpagamento:string;begin

Page 13: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 13

if(MessageDlg(‘Deseja finalizar a venda?’,mtConfirmation,[mbYes,mbNo],0)=mrYes)then begin Form1.ACBrECF1.SubtotalizaCupom; sValorpagamento:=InputBox(‘ACBr’,’Informe o valor pago’,’’); Form1.ACBrECF1.EfetuaPagamento(‘01’,StrToFloat(sValorpagamento)); Form1.ACBrECF1.FechaCupom(‘Obrigado Volte Sempre!’); Close; end;end;

Veja o formulário com valores para teste na figura 3:

Veja a Figura 3.

Após a venda dos itens e o pagamento, a ECF ficará livre para uma nova venda.

Fique atento para os tipos de dados necessá-rios nas passagens de parâmetros para as funções, para evitar erros de conversão.

Além da venda de itens e principais leituras, como a Leitura X e Redução Z, o ACBr, permite também o completo gerenciamento da ECF, como o cadastro de formas de pagamento e a emissão de relatórios gerenciais.

Ao se trocar o modelo de ECF, nenhuma alteração precisará ser feita no código, já que o ACBrECF, envia os comandos de acordo com o modelo de ECF configurada em sua propriedade Modelo. Os modelos suportados são descritos no ínicio desse artigo.

Conclusão

Na área de automação comercial, o projeto ACBr sem dúvida é uma grande ajuda quando pre-cisamos operar com ECF’s, pois sua portabilidade e extensibilidade garante um grande ganho de desempenho no desenvolvimento.

O projeto ACBr, é totalmente open source, podendo ser adquirido nos seguintes links:

Pagina principal ACBRhttp://acbr.sourceforge.net/drupal/

Ferramenta de controle de versão SVN no Windows (Tortoise):

h t t p : / / a c b r. s o u r c e f o r g e . n e t /drupal/?q=node/37

Para instalar o componente NFe:h t t p : / / a c b r. s o u r c e f o r g e . n e t /

drupal/?q=node/36

FAQ - ACBrNFeh t t p : / / a c b r. s o u r c e f o r g e . n e t /

drupal/?q=node/38

Nesses links também se pode obter maiores informações sobre os componentes.

Abraços e até a próxima.

Figura 3

Consultor Técnico The Club.

Sobre o autor

Antonio Spitaleri Neto

[email protected]

Page 14: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201014

Olá pessoal,

Tem certos momentos em que quebra-mos a cabeça tentando montar fórmulas, que-ries, procedures e todo tipo de truques para resolver determinadas situações em nossos bancos de dados. Por exemplo: precisamos realizar uma grande atualização em nosso banco de dados, mas devido a toda integrida-de referencial que temos através de triggers, um único Update dispararia centenas, mi-lhares de outras ações que, provavelmente, sairiam de nosso controle. Então uma saída seria a desativação das triggers. Mas como desativar todas as triggers de nosso banco? Usando o comando Alter trigger tal_de_tal inactive? Uma a uma? Pois é, um tanto quanto complicado, não?

Ou mesmo essa outra situação: Temos uma coluna em nossos bancos chamada Tipo_Cliente que é validada por uma Check Constraint determinando que os valores possíveis são ‘F’ (Pessoa Física) e ‘J’ (Pessoa

I N D O M A I S A L É M E X P L O R A N D O A S TABELAS DE SISTEMA

INTERBASE/FIREBIRDJurídica). Quando nós criamos essa Constraint não especificamos o nome da mesma. Então o banco de dados cria um nome aleatório do tipo CHECK$10. Agora precisamos alterar essa validação, acrescentando um novo valor. Para isso precisamos dropar a constraint e recria-la novamente. Mas como dropar a constraint se não sabemos o nome da mesma? Outra tarefa difícil de cumprir.

Por isso nesse mês abordaremos um as-sunto diferente: o uso das tabelas de sistema em bancos de dados InterBase/Firebird.

São tabelas que contém informações extremamente úteis e que, se bem utilizadas e manipuladas, podem nos ajudar a ir muito mais além na administração e manutenção de nossos bancos.

Na prática podemos realizar todo tipo de comando DML (Data Manipulation Language) sobre as tabelas de sistema, respeitando algu-mas restrições que o próprio banco de dados

impõe para manter a integridade interna. Então vamos lá:

AS TABELAS DE SISTEMA

Assim como outros objetos internos, as tabelas de sistema são todas aquelas cujo nome se iniciam com os caracteres RDB$ ou, no caso do InterBase, também TMP$. Essa nomenclatura é de uso exclu-sivo do banco de dados e não pode ser utilizado na criação de novas tabelas pelo usuário. As TMP$ são tabelas temporárias de sistema, utilizadas no recurso de monitoramento do banco de dados. Já as RDB$ são as tabelas de sistema responsáveis por guardar todo tipo de informação relativa, principalmente, ao metadata do banco de dados, à estrutura do banco.

Quando criamos um banco de dados, o sis-tema já cria automaticamente as tabelas RDB$. São elas:

Veja a Tabela.

Page 15: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 15

Tabela de Sistema FuncionalidadeRDB$CHARACTER_SETS Descreve todos os tipos de Character Sets disponíveis no banco de dados.

RDB$CHECK_CONSTRAINTS Grava informações sobre todas as Constrainst do tipo Check presentes no banco de dados. Também armazena informações sobre todas as Constraints das colunas marcadas como Not Null.

RDB$COLLATIONS Descreve as regras das Collations permitidas para uso do banco de dados.

RDB$DATABASE Salva informações sobre o banco de dados.

RDB$DEPENDENCIES Armazena todos os tipos de dependência entre os objetos do sistema. Tabelas / Stored Procedures / Triggers, enfim. É por aqui que o banco de dados valida se uma coluna pode ser alterada / excluída sem afetar outros objetos.

RDB$EXCEPTIONS Descreve todas as exceções de erro geradas e utilizadas pelas Stored Procedures, inclusive as exceções criadas pelo usuário.

RDB$FIELDS Contém informações sobre as características de cada coluna e domínio do banco de dados. Informações sobre valores default, not null, campos computados, enfim. Todas as colunas de todas as tabelas são referenciadas nessa tabela.

RDB$FIELD_DIMENSIONS Descreve o tamanho de cada coluna.

RDB$FILES Lista informações sobre todos os arquivos secundários do tipo shadow que estão em uso no banco de dados.

RDB$FILTERS Contém informações sobre filtros de campos do tipo Blob.

RDB$FORMATS Uma tabela interessante. Ela armazena informações sobre o versionamento de alterações realizadas nas tabelas do banco. Todas as vezes que executamos um comando de Alter/Drop/Create Table essa tabela grava o número dessa alteração. E isso que permite que uma aplicação possa acessar tabelas alteradas sem a necessidade de ser recompilada. O sistema permite que sejam feitas até 255 alterações na estrutura de tabelas. Ao atingir esse limite, um backup e um restore do banco precisa ser feito para zerar esse contador e permitir novas alterações.

RDB$FUNCTION_ARGUMENTS Define atributos de funções utilizadas pelo banco de dados, inclusive as UDFs.

RDB$FUNCTIONS Descreve as UDFs utilizadas pelo banco de dados.

RDB$GENERATORS Contém informações sobre todas as Generators utilizadas pelo banco de dados.

RDB$INDEX_SEGMENTS Uma tabela de sistema muito importante que grava informações sobre todas as colunas que são referenciadas em todos os índices do banco de dados. Modificar manualmente essa tabela pode causar grandes corrupções!

RDB$INDICES Descreve todos os índices criados no banco de dados. Cada índice dessa tabela deve ser suas respectivas referencias na tabela RDB$INDEX_SEGMENTS.

RDB$LOG_FILES Essa tabela não é mais utilizada nos bancos de dados InterBase/Firebird, mas permanece listada por legado.

RDB$PAGES Uma tabela bem técnica, que grava informações sobre cada página de dados alocada do banco de dados. Qualquer tipo de modificação manual nessa tabela irá corromper o mesmo.

RDB$PROCEDURE_PARAMETERS Essa tabela grava informações sobre os parâmetros (input e output) usados em todas as Stored Procedures do banco de dados.

RDB$PROCEDURES Contém a descrição das Stored Procedures do banco de dados.

RDB$REF_CONSTRAINTS Grava informações sobre as Constraints de Integridade Referencial usadas no banco (Primary e Foreing Keys).

RDB$RELATION_CONSTRAINTS Aqui são listadas as relações entre as Constraints e de Integridade Referencial e as respectivas tabelas relacionadas.

RDB$RELATION_FIELDS Descreve informações complementares sobre as colunas e domínios do banco de dados, bem como as relações entre as colunas e as tabelas.

RDB$RELATIONS Define algumas características de tabelas e Views.

RDB$ROLES Listas todos os Roles criados no banco, bem como o usuário dono desse Role.

RDB$SECURITY_CLASSES Define as listas de controle de acesso (ACLs) criadas no banco, bem como a relação dessas regras com os objetos do sistema.

RDB$TRANSACTIONS Grava informações sobre todas as transações multi-banco que estão em uso no sistema.

RDB$TRIGGER_MESSAGES Contém informações sobre todas a mensagens de Triggers, bem como as Triggers relacionadas às mensagens.

RDB$TRIGGERS Descreve todas as Triggers do banco de dados.

RDB$TYPES Lista todos os tipos de dados e apelidos para os Character Sets e Collations usados no banco de dados.

RDB$USER_PRIVILEGES Contém informações sobre o direito de acesso de cada usuário criado no banco de dados. Sempre que usamos os co-mandos Grant e Revoke, o sistema grava essas referências nessa tabela.

RDB$VIEW_RELATIONS Aqui são listadas as relações entre as Views e suas respectivas tabelas.

Page 16: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201016

Também pode existir outras tabelas de sistema de forma distinta entre o InterBase e o Firebird, conforme a ODS (On Disk Structure) do banco de dados.

VISUALIZANDO AS TABELAS DE SIS-TEMA

Para acessar e visualizar as tabelas de sistema devemos:

1. Usando o utilitário de linha de comando ISQL, executamos o comando:

SQL> show system; RDB$CHARACTER_SETS RDB$CHECK_CONSTRAINTS RDB$COLLATIONS RDB$DATABASE RDB$DEPENDENCIES RDB$EXCEPTIONS[...]SQL>

2. Usando o utilitário gráfico IBConsole, selecionamos no menu:

3. Usando o utilitário gráfico IBExpert,

marcamos na propriedade da conexão:

Veja a imagem 2.

MANIPULANDO AS TABELAS DE SIS-TEMA

Devemos sempre tomar cuidado antes de assim proceder, mas vamos dar alguns exemplos de comandos DML que podemos executar sobre as tabelas de sistema.

Ampliando o tamanho de um campo Char/Varchar:

Muitas vezes precisei ampliar o tamanho de

Imagem 2

uma coluna Char/Varchar. Por exemplo: Precisamos ampliar a coluna NOME de 30 para 60 caracteres. Mas como fazer de uma só vez em todas as tabelas do banco de dados onde essa coluna existe? Mani-pulando as tabelas de sistema:

Update rdb$fieldsSet rdb$field_length = 60Where rdb$field_name = (select f.rdb$field_source from rdb$relation_fields f where f.rdb$field_name = ‘NOME’)

Esse comando irá buscar todas as colunas des-critas com o nome “NOME” e aumentar na tabela que descreve os campos o Length dessa coluna para 60 caracteres.

Ativando e Desativando Triggers:

Quando precisamos realizar uma atualização em massa no banco de dados ou quando temos um banco de dados vazio que precisa ser populado, po-demos nos deparar com um problema: as Triggers. Isso porque, muitas vezes usamos as Triggers para realizar a integridade referencial de nossos bancos. Ai quando vamos inserir um dado em determinada tabela, a Trigger impede por não existir relação com

outra tabela principal, por exemplo. Precisamos então rodar comandos do tipo Alter Trigger ... Inac-tive/Active. Mas como fazer isso de forma prática quando temos centenas / milhares de Triggers? Executando o comando DML abaixo:

UPDATE RDB$TRIGGERSSET rdb$trigger_inactive = 1WHERE (rdb$system_flag = 0 or rdb$system_flag IS NULL) AND rdb$trigger_name NOT LIKE ‘CHECK%’ AND rdb$trigger_name NOT LIKE ‘RDB$%’

Esse comando irá desativar todas as Triggers do banco de dados, com exceção das Triggers de sistema e das Checks Constraints. Para reativar novamente as mesmas, basta realizar o Update novamente, ajustando o valor para “0” (Zero).

Apagando Checks Constraints sem saber o nome:

Como no exemplo que demos na abertura do nosso artigo, como podemos apagar todas as Che-cks Constraints relacionadas à uma determinada coluna de nosso banco de dados, se não sabemos o nome de nossa Check Constraint? Basta executar o comando DML abaixo:

Page 17: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 17

DELETE FROM RDB$RELATION_CONSTRAINTS AWhere (Select count(*) from RDB$CHECK_CONSTRAINTS B, RDB$TRIGGERS C where (A.RDB$CONSTRAINT_TYPE = ‘CHECK’) and (A.RDB$CONSTRAINT_NAME = B.RDB$CONSTRAINT_NAME) and (B.RDB$TRIGGER_NAME = C.RDB$TRIGGER_NAME) and (C.RDB$TRIGGER_TYPE = 1) and (A.RDB$RELATION_NAME in (SELECT DISTINCT r.rdb$relation_name FROM rdb$check_constraints C JOIN rdb$relation_constraints R ON (C.rdb$constraint_name = R.rdb$constraint_name) WHERE C.rdb$trigger_name IN (SELECT D.rdb$dependent_name FROM rdb$dependencies D WHERE D.rdb$field_name = ‘TIPO_CLIENTE’ and d.rdb$dependent_name like ‘CHECK%’))

)) > 0;

Esse nosso comando irá apagar todas as Checks Constraints que validarem a coluna Tipo_Cliente, em todas as tabelas do banco de dados. Depois, podemos recriar as mesmas com a nova regra de validação. Rápido e Seguro.

Resgatando o MAC Address do Servidor Inter-Base/Firebird:

Recentemente em um artigo nosso aqui na The

Club Megazine comentamos a respeito do uso das UDFs. Segue um exemplo de uso de UDF contra uma tabela de sistema:

Select F_UUID1MACMAC(F_UUID1MAC()) from rdb$database;

Esse comando executado a partir de qual-quer computador cliente retornará o endereço Mac Address do servidor do banco de dados. Isso pode ser muito útil por exemplo para se criar uma rotina de validação da aplicação para liberação de licenças de uso.

Trabalhando com Descrições em Tabelas:

Esse é outro ponto interessante. É muito comum encontrar bancos de dados com centenas de tabelas, mas onde o nome da tabela não iden-tifica seu real propósito. Por exemplo: ao invés de chamar uma tabela de cadastros de produto de TABPRODUTOS, o nome da tabela é algo do tipo T01P007LJ. Então novo desenvolvedor ou mesmo um usuário mais experiente acaba ficando perdido ao tentar encontrar uma determinada tabela.

Uma maneira interessante de se tratar esse problema é criando uma descrição para as tabelas de sistema. Para isso usamos o comando DML:

UPDATE RDB$RELATIONS SET RDB$DESCRIPTION=’Cadastro de Produtos’ WHERE RDB$RELATION_NAME=’ T01P007LJ’;UPDATE RDB$RELATIONS SET RDB$DESCRIPTION=’Cadastro

de Tamanhos’ WHERE RDB$RELATION_NAME=’ T02P007LJ’;UPDATE RDB$RELATIONS SET RDB$DESCRIPTION=’Cadastro de Cores’ WHERE RDB$RELATION_NAME=’ T03P007LJ’;UPDATE RDB$RELATIONS SET RDB$DESCRIPTION=’Tabelas de Preco’ WHERE RDB$RELATION_NAME=’ T04P009LJ’;UPDATE RDB$RELATIONS SET RDB$DESCRIPTION=’Imagens de Produtos’ WHERE RDB$RELATION_NAME=’ T05P015LP’;

E assim por diante. Quando abrimos o uti-litário IBExpert, podemos facilmente identificar as tabelas:

Veja a Imagem 3.

Ou mesmo podemos executar um comando DML para pesquisar uma determinada tabela pela sua descrição:

Select rdb$relation_name, rdb$description from rdb$relations where rdb$description like ‘%rodutos%’;

Imagem 3

Page 18: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201018

Retornaria algo como:

CONCLUSÃO

E esses são apenas alguns exemplos. Nova-mente explorando mais dos recursos de nossos bancos de dados. Se pesquisarmos mais e estu-darmos as tabelas de sistema de nossos bancos, podemos extrair muito mais. Claro e novamente repetindo: tudo com muito cuidado para não der-rubar alguma integridade ou mesmo corromper nossos bancos. Mas recomendo a todos a leitura complementar do Capitulo 6 do guia Language Reference do InterBase SMP 2009, que contém informações completas sobre as tabelas de sistema e sobre as tabelas temporárias de sistema. Afinal,

RDB$RELATION_NAME RDB$DESCRIPTIONT01P007LJ Cadastro de Produtos

T05P015LP Imagens de Produtos

as informações estão lá o tempo todo. Cabe a nós desenvolvedores irmos mais além, usar essas informações à nosso favor.

Nos vemos no próximo artigo para falar mais sobre o InterBase e seus recursos. Valeu pessoa e Até lá!

Referência:

InterBase 2009 Language Reference – cap. 6.http://edn.embarcadero.com

Felipe Santos é especialista em InterBase. Trabalha com o InterBase desde 2001. atuando como consultor e instrutor do produto em todo Brasil. Especialista em ambientes críticos. Atua e trabalha com os maiores clientes do InterBase no Brasil. Participante ativo na comunidade, com diversos artigos publicados. Participante do grupo de beta testers mundial do produto. Palestrante em eventos como IB Tour, Borcon Conference, CodeRage Latin América, Delphi Developers Day, Linux Day, entre outros. Atualmente trabalhando na área técnica do InterBase na Presence Tecnologia – agente oficial especializado do produto no Brasil.

Sobre o autor

Felipe Santos

[email protected]

Page 19: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 19

As Stored Procedures e Triggers são mais conhecidas no Firebird, mas também são mui-to importantes na otimização do desempenho de um Banco de Dados no MySQL, neste arti-go mostrarei o que elas são, como funcionam no MySQL e farei alguns exemplos.

STORED PROCEDURES

Introduzidas a partir da versão 5.0 do MYSQL as Stored Procedures (SP) ou Procedimentos Ar-mazenados são um conjunto de comando SQL que podem ficar armazenados no servidor e poupar os usuários da necessidade de enviar extensos comandos SQL ao servidor só sendo necessário fazer a chamada a SP.

As vantagens do uso das SP’s são muitas, entre as principais que posso destacar estão:

STORED PROCEDURES

E TRIGGERS NO MYSQL

• Melhora do desempenho – por se-rem armazenadas e processadas no servidor elas enviarão ao usuário somente os resulta-dos das consultas diminuindo assim o trafego na rede;

• Economia de código – é necessária apenas uma linha de código para se chamar uma SP já que a instrução SQL está toda en-capsulada no corpo da SP, você não terá mais que escrever várias linhas toda vez que quiser uma operação específica em seu banco;

• Facilidade de manutenção – elas podem ser alteradas sem a necessidade de se alterar as aplicações que as utilizam e sem importar a linguagem em que foi escrita essa aplicação;

• Segurança – os usuários terão acesso somente as SP’s e não as tabelas, isso diminui a possibilidade de algum usuário fazer alguma

alteração que prejudique o Banco de Dados;

• Distribuição de tarefas – as tarefas da criação de uma aplicação podem ser divi-didas entre um profissional especializado em Banco de Dados e um Programador que criará a aplicação.

As SP são basicamente classificadas em três tipos:

1. As que retornam algum valor, como a contagem de registros de uma tabela;

2. As que retornam registros funcionan-do como um Select , e;

3. As que fazem ações específicas no banco, como inserções, alterações, atualiza-ções etc.

Page 20: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010

STORED PROCEDURES NO MYSQL

A sintaxe geral de uma SP no MySQL é a seguinte:

CREATE PROCEDURE nome_proc([parâmetro ...]) [características]BEGIN

Corpo da SP;

END;

Onde:

• Nome_proc - aqui se define o nome da procedure, um padrão muito adotado en-tre os desenvolvedores é SP_nome_da_pro-cedure;

• Parâmetro – os parâmetros utilizados em SP no MySQL dividem-se em três:

1. IN – São os parâmetros de entrada que serão trabalhados no corpo da SP e pro-duzirão algum resultado;

2. OUT – É o parâmetro interno que re-torna algum resultado para o lado externo;

3. INOUT - É o parâmetro que pode funcionar das duas formas.

• Características – definem o tipo da procedure, se determinística ou não, questões de segurança do banco de dados e linguagem de escrita da SP,não setem a obrigatoriedade de declara – las quand se escrevea SP ;

• Corpo da SP – onde são escritos os comandos SQL.

TRIGGERS

As triggers (ou gatilhos em português) são

comandos procedurais executados automatica-mente em resposta a algum evento executado no banco de dados, como por exemplo na inserção de um registro em uma tabela de pessoas, a trigger automaticamente gerará na tabela de salários um campo referente ao salário daquela pessoa.

As triggers são usadas geralmente para:

• Para manter a integridade entre as tabelas: podem ser criados grandes processos de controle dos relacionamentos entre as ta-belas, principalmente aos usuários de tabelas MyISAM que não suportam relacionamnetos via chave estrangeira;

• Manter a segurança do Banco: as tri-ggers podem controlar o acesso, atualizações e alterações nas tabelas;

• Melhorar o desempenho do banco: imagine um banco com 500.000 registros que de tempos em tempos requer uma simples alteração nos registros, atrvés de uma trigger essas alterações podem ser feitas automati-camente através da trigger.;

• Auditoria do Banco de Dados: por serem executadas automaticamente são excelentes ferramentas para auditria do BD.

TRIGGERS NO MYSQL.

A sintaxe geral de uma Trigger no MySQL é a seguinte:

CREATE [DEFINER = { USER | CURRENT USER}]

TRIGGER nome_trigger tempo_trigger evento_trigger ON nome_tabela FOR EACH ROW

corpo_trigger

Onde:

• DEFINER: checa quais os privilégios que usuário do banco tem para disparar a trigger. Quando a trigger é criada esse campo é preenchido por padrão com CURRENT_USER ou pode ser preenchida com o usuário(ex: ‘bruno’@’localhost’);

• nome_trigger: define-se o nome da trigger, o padrão adotado entre os desenvol-vedores é TRG_nome_trigger;

• tempo_trigger: aqui se define quan-do a trigger será executada:

• BEFORE: a trigger será ativada antes do comando que a disparou;

• AFTER: a trigger será ativada depois do comando que a disparou;

• evento trigger: o evento que será executado quando a trigger for disparada:

• INSERT: um ou mais registros serão inseridos em uma tabela;

• UPDATE: um ou mais registros serão atualizados em uma tabela;

• DELETE: um ou mais registros serão apagados em uma tabela;

• nome_tabela: tabela onde a trigger trabalhará;

• corpo_trigger: comandos executados pela trigger.

EXEMPLOS

Para ilustrar melhor as explicações vamos criar

Page 21: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 21

alguns exemplos de Triggers e Stored Procedures.O primeiro passo é criar as tabelas, para este

exemplo vamos criar duas tabelas, uma tabela de pessoas e outra de usuários. Abaixo seguem os scripts de criação das tabelas:

PESSOAS

Essa tabela servira para o cadastro de pessoas, como por exemplo clientes e funcionários, essa especificação se dará no campo PESSOA_TIPO que receberá G para gerente(que terá todos os privilé-gios), C – para cliente ou F – para funcionário.

CREATE TABLE `pessoas` ( `ID_PESSOA` INTEGER(11) NOT NULL AUTO_INCREMENT, `PESSOA_NOME` VARCHAR(80) NOT NULL, `PESSOA_RG` VARCHAR(15) DEFAULT NULL, `PESSOA_TIPO` CHAR (1) DEFAULT NULL, PRIMARY KEY (`ID_PESSOA`)) ENGINE=InnoDB;

USUARIOS

Essa tabela guardará os dados dos usuários de um suposto programa, desde que eles sejam definidos com F no campo PESSOA_TIPO. O campo USUARIO_TIPO deve ser marcado com A – Adminis-trador ou C- Comum sendo que só o Administrador tem permissões para inserir registros na tabela de pessoas.

CREATE TABLE `usuarios` ( `ID_USUARIO` int(11) NOT NULL auto_increment, `USUARIO_NOME` varchar(80) default NULL, `USUARIO_SENHA` varchar(35) default NULL, `USUARIO_TIPO` char(1) default NULL, `FK_PESSOA_USUARIO`

int(11) default NULL, PRIMARY KEY (`ID_USUARIO`), KEY `FK_PESSOA_USUARIO` (`FK_PESSOA_USUARIO`), CONSTRAINT `USUARIO_PESSOA_FK` FOREIGN KEY (`FK_PESSOA_USUARIO`) REFERENCES `pessoas` (`ID_PESSOA`)) ENGINE=InnoDB DEFAULT CHARSET=latin1

TRG_CRIP_SENHA

Agora vamos criar nossa primeira trigger, essa trigger se encarregará de criptografar a senha de usuário quando este for inserido, o método de criptografia é o MD5 que já é uma função presente no banco MySQL, o MD5 é um algoritmo unidire-cional que criptografa uma string e não permite que essa criptografia seja revertida. Percebam que usamos o operador NEW (NEW. USUARIO_SENHA) esse operador significa que queremos o dado que acaba de ser inserido, se porventura apagássemos esse registro poderíamos recuperá – lo através do operador OLD (OLD. USUARIO_SENHA).

CREATE TRIGGER TRG_CRIP_SENHA BEFORE INSERT ON `usuarios`FOR EACH ROWBEGIN SET NEW.USUARIO_SENHA = MD5(NEW.USUARIO_SENHA);END;

SP_ADD_USUARIOS

O nosso próximo passo é criar uma Stored Procedure que será usada em conjunto com a próxima trigger e que quando executada incluirá dados na tabela de usuários.

CREATE PROCEDURE SP_ADD_USUARIOS (IN USUARIO VARCHAR (80),IN SENHA VARCHAR (35),IN TIPO CHAR(1),IN FK_PESSOA INT)BEGIN INSERT INTO `usuarios` (USUARIO_NOME, USUARIO_SENHA, USUARIO_TIPO,FK_PESSOA_USUARIO) VALUES (USUARIO,SENHA,TIPO,FK_PESSOA);END;

TRG_USUARIOS

Essa trigger incluirá automaticamente uma pessoa cadastrada na tabela de pessoas, desde que seu pessoa tipo na tabela seja F, na tabela de usuários como um usuário do sistema. Por padrão, que será definido na trigger, o nome de desse usuário será o seu nome em letras minúsculas, a senha será 123456 e o tipo será definido como C - Comum.

CREATE TRIGGER TRG_USUARIOS AFTER INSERT ON `pessoas`FOR EACH ROWBEGIN IF (NEW.ID_PESSOA IS NOT NULL) AND (NEW.PESSOA_TIPO = ‘G’) THEN CALL SP_ADD_USUARIOS(LOWER(NEW.PESSOA_NOME),’123456’,’A’,NEW.ID_PESSOA); ELSE IF (NEW.ID_PESSOA IS NOT NULL) AND (NEW.PESSOA_TIPO = ‘F’) THEN CALL SP_ADD_USUARIOS(LOWER(NEW.PESSOA_NOME),’123456’,’C’,NEW.ID_PESSOA); END IF; END IF; END

Page 22: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201022

TESTES

Agora vamos efetuar alguns testes nesse banco para verificar o funcionamento das Triggers e Stored Procedures. Para efetuar esses testes estou usando a IDE Gráfica EMS SQL Manager Lite for MySQL que é gratuita e pode ser encontrada no seguinte endereço:

Vamos inserir um registro na tabela de PESSO-AS com o tipo definido com G –GERENTE.

INSERT INTO `pessoas` (PESSOA_NOME, PESSOA_RG, PESSOA_TIPO)VALUES (‘BRUNO’,’12.345.678-9’,’G’);

Veja a Imagem 1.

No momento da inserção a trigger que insere um usuário(TRG_USUARIOS) é automaticamente executada e gera na tabela de usuários um novo registro com a senha já criptografada (TRG_CRIP_SENHA), e como o PESSOA_TIPO é = G esse usuário será um administrador.

Veja a Imagem 2.

Vamos inserir agora mais dois registros, um funcionário (que também é um usuário do sistema) e um cliente.

INSERT INTO `pessoas` (PESSOA_NOME, PESSOA_RG, PESSOA_TIPO)VALUES(‘DANIEL’,’87.654.321-0’,’F’),(‘FREDERICO’,’87.654.321-0’,’C’);

COMMIT;

Veja a Imagem 3.

Na tabela de usuários foi gerado apenas mais

Imagem 1

Imagem 2

Imagem 3

Imagem 4

um registro, referente ao funcionário DANIEL

Veja a Imagem 4.

Vamos criar agora uma Stored Procedure que controlará a inserção de dados na tabela PESSOAS.

SP_PERMISSOES

Essa procedure quando executada servirá para incluir dados na tabela de pessoas, mas ela controlará quem o fará, só poderão incluir registros usuários cadastrados como A – Administrador e que tenham digitado o nome e senha de usuário correta, caso o usuário seja C – comum retornará uma mensagem avisando que não é possível fazer essa inserção.

CREATE PROCEDURE SP_PERMISSOES (IN USUARIO VARCHAR (80),IN SENHA VARCHAR (35),IN NOME VARCHAR(80),

IN RG VARCHAR(15),IN TIPO CHAR(1))BEGINDECLARE V_TIPO CHAR(1);DECLARE V_SENHA VARCHAR

(35); SELECT USUARIO_TIPO, USUARIO_SENHA INTO V_TIPO, V_SENHA FROM USUARIOS WHERE USUARIO_NOME = USUARIO; IF V_TIPO = ‘A’ AND V_SENHA = MD5(SENHA) THEN INSERT INTO `pessoas` (PESSOA_NOME, PESSOA_RG, PESSOA_TIPO) VALUES (NOME, RG, TIPO); ELSE SELECT ‘VOCÊ NÃO TEM PERMISSÃO PARA EXECUTAR ESSA TAREFA’ AS AVISO; END IF; END

Vamos agora testar essa SP:

CALL SP_PERMISSOES(‘bruno’,’123456’,’ANTONIO’,’71.825.936.-4’,’C’)

Percebam que o registro ANTONIO foi inse-rido:

Page 23: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 23

Veja a Imagem 5.

Vamos tentar inserir um registro como um usuário C – comum:

CALL SP_PERMISSOES(‘daniel’,’123456’,’JEREMIAS’,’84.369.521-7’,’G’)

Ele retornará uma mensagem de erro:

Veja a Imagem 6.

CONCLUSÃO

Neste artigo procurei demonstrar de forma simples algumas das operações que podem ser feitas com Triggers e Stored Procedures no MySQL, mas elas podem ser usadas de muitas outras for-mas na busca de um melhor desempenho do seu banco, sempre que possível as utilize.

E isso é tudo pessoal, até outra hora.

Imagem 5

Imagem 6

Consultor Técnico The Club.

Sobre o autor

Bruno Alcarás

[email protected]

Page 24: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201024

Olá, Então pessoal como alguns devem saber no dia 12/04/2010 foi lançado o Visual Studio 2010 oficialmente e na edição de hoje eu vou falar sobre algumas novidades dessa versão, nessa edição eu vou focar nas área e nas novidades que mais gostei área de arqui-tetura e modelos UML.

As versões

Ao contrário de seus antecessores, o Visual Studio 2010 conta com SKUs (edições) mais simpli-ficadas, de anteriormente 9 para simplesmente 4 agora: Ultimate, Premium, Professional e a versões Express. Irei abordar aqui individualidades de cada uma das três versões pagas, Ultimate, Premium e Professional:

Visual Studio Professional

Além dos modelos básicos de programação WCF, WPF, Windows Form, Silverlight, WebAppli-cation e a novidade agora é Azure ou seja Cloud Computing, e essa nova versão conta com Unit Tests, ao contrário da versão Professional do Visual Studio 2008.

Visual Studio Premium (além das funcionali-dades da versão Professional):

• Debugging e desenvolvimento de aplicações avançado

• Unit Tests com cobertura de código (Code Coverage - mostra quanto por cento do código está sendo testado), prioritização de testes, análise, métrica e otimização de código

• Desenvolvimento e testes unitários de banco de dados

• Diagramas de arquitetura (apenas leitura)

Visual Studio Ultimate (além das funcionalida-des da versão Premium):

• Debugging histórico com IntelliTra-ce

• Ferramentas de testes compreensi-vas

• Ferramentas avançadas de UML • Ferramentas de descoberta de arqui-

tetura • Test Case e gerenciamento do labo-

ratório de testes

Page 25: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 25

Modelagem UML

Para criar um modelo novo basta clicar em New Project e escolher a opção Modeling Projects e escolher o template Modeling Project, depois só indique o caminho aonde será salvo e pronto você terá um Projeto de modelos, esse projeto você pode tranquilamente fazer controle de versão com o Visual Studio team System ( falarei mais sobre ele em outro artigo ). Figura 1

Veja a figura 1.

Diagrama de Sequência

A UML significa muito para arquitetos e ana-listas de sistema. Parqa criar os modelos basta clicarmos com o botão direito sobre qualquer mé-todo de classe que desejemos visualizar o diagrama de sequência e escolhermos a opção Generate Sequence Diagram, que em seguida será aberta uma janela para customização do método, como profundidade, referências externas, entre outras. Após o OK, teremos o Diagrama de Sequência do método, como visto a seguir: Figura 2

Veja a figura 2.

Diagrama de Dependências

Um sistema, por menor que seja, terá algumas referências (bibliotecas externas) o acompanhan-do, seja elas do próprio sistema ou de terceiros. Mas a medida que o projeto vai crescendo, suas referências também vão aumentando, dificultando assim a visualização do que cada parte do sistema necessita.

Com o diagrama de sequência do do Visual Studio 2010, fica mais fácil fazer e de visualizar o mesmo melhorando a vida do arquiteto do sistema.

Para que geremos um novo diagrama de de-pendências, basta irmos no menu Architecture -> Generate Dependency Graph e escolher o tipo de diagrama que será mostrado, por assembly, por namespace, entre outras opções. Veja aqui um

Figura 1. Criando um projeto de diagrama

Figura 2. Diagrama de sequência

exemplo: Figura 3 Vejaa figura 3.

Note que cada dependência está contraída, po-

dendo ser expandida até um nível mais profundo e com isso os arquitetos, desenvolvedores, analistas e designers conseguem entender e vizualizar me-lhor o impacto das alterações a serem realizadas.

Page 26: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201026

Figura 3. Diagrama de dependências

Figura 4. Diagrama de componente

Diagrama de Componentes

Quando utilizamos componentes de terceiros em nossos sistemas, várias vezes nos perguntamos como eles se relacionam com o código desenvolvi-do pela equipe. Esta pergunta surge principalmente quando um desenvolvedor novo entra no time que já tem um projeto em andamento. Como a UML conta com o diagrama de componentes, a equipe de desenvolvimento do Visual Studio achou inte-ressante incorporá-lo ao template de projetos de modelagem, para que seja de fácil visualização e modificação para aqueles que estão entrando no time depois de um tempo de desenvolvimento.

Este diagrama contém os seguintes objetos na

toolbox: Component, Provided Interface, Required Interface, Part Assembly, além dos objetos de re-lacionamento e comentários. Confira como é seu design no Visual Studio: Figura 4

Veja a imagem 4.

Diagrama de Camadas

Hoje em dia, nos deparamos com diversos padrões de projeto que dividem o sistema em camadas. Seja MVC (Model-View-Controller), MVP (Model-View-Presenter), MVVM (Model-View-ViewModel) ou N camadas, esta divisão de camadas está presente no nosso dia a dia, pois permite uma manutenibilidade boa, além de não ficarmos focados em apenas um tipo de visão, ou banco de dados, por exemplo.

Por isso é importante enxergarmos o sistema

como um todo dividido em algumas partes, para sabermos qual parte faz o quê. Partindo deste princípio, o diagrama de camadas foi criado, e agora o Visual Studio conta com um template para diagramação das mesmas.

Apenas arrastando itens da toolbox, podere-

mos facilmente, por exemplo, criar um diagrama de camadas MVC, de acordo com a figura a seguir: Figura 5

Veja a figura 5.

Figura 5. Diagrama de camadas

Page 27: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 27

Agora que já falamos de UML e diagramas vou falar um pouco das novas funcionalidades do editor.

References Highlighting

Agora é possível encontrar onde cada proprie-dade e outros símbolos definidos em determinada classe estão sendo usados, através do recurso Refe-rences Highlighting. Clicando sobre qualquer refe-rência de determinada propriedade da sua classe, a IDE vai destacar todas as suas ocorrências. Além disto, ainda é possível navegar pelas referências, com as teclas CTRL + SHIFT + Seta para cima ou CTRL + SHIFT + Seta para baixo, levando para a ocorrência anterior ou superior, respectivamente.

Veja a figura 6.

Call Hierarchy

Quem nunca precisou saber quais métodos chamam outros métodos enquanto está melho-rando aquele código imenso? A nova versão do Visual Studio agora lhe possibilita isto, através do Call Hierarchy.

Como exemplo, criei um projeto Silverlight, que conta com a MainPage.xaml.cs, uma classe chamada ClassePai e outra chamada ClasseFilha. Criei alguns métodos para interpretação, o Me-todoPai na ClassePai, que chama o MetodoFilho, na ClasseFilha. E por sua vez, no construtor da MainWindow.xaml.cs, o MetodoPai é chamado. Seria algo parecido como:

MainPage.xaml.cs -> MetodoPai -> Metodo-Filho.

Indo lá no cabeçalho do MetodoFilho, clicamos com o botão direito, indo em View Call Hierarchy, o que nos abrirá a seguinte janela:

Veja a figura 7.

Figura 6. - Propriedade Nome selecionada, mostrando as ocorrências na classe

Trabalha a quase 7 anos com Delphi, trabalha na empresa Benner Sistemas (www.benner.com.br ) na área de tecnologia desenvolvendo fer-ramentas em Delphi e como hobby e visão de mercado está migrando seus conhecimentos para a plataforma .NET. Faz parte do grupo .NET Blumenau http://dotnetblumenau.ning.com/ . Possue certificação 70-536 (Microsoft .NET Framework 2.0 Application Development Foundation ) . Twitter: djonatastenfen - blog http://www.djonatastenfen.blogspot.com/

Sobre o autor

Djonatas Tenfen

[email protected]

Figura 7. - Chamadas ao MetodoFilho, e chamadas do MetodoFilho

Conclusão

Então o que concluimos é que a Microsoft está trabalhando intensamente em cima das necessi-dades da comunidade e dos Feedback enviados. E esses novos diagramas e funcionalidades facilitam a vida dos arquitetos, analistas e desenvolvedores, vale a pena conferir. Mais informações podem ser obtidas em:

http://www.microsoft.com/visualstudio/en-us/

Page 28: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201028

Dicas DELPHILimitar número de caracteres digitados em um Memo

ou RichEdit

Mude a propriedade MaxLenght do Memo ou RichEdit para o valor desejado(neste exemplo usaremos 140), adicione também uma label para mostrarmos a contagem dos caracteres.

No evento OnChange

Label1.Caption:= IntToStr(length(Memo1.Text)); // uma label mostrando o número de caracteres digitados

No evento KeyUp

if length(Memo1.Text) = 140 then // se o tamanho do memo igual a 140 então ShowMessage(‘Somente 140 caracteres permitidos’); // mostra mensagem

Serial HD

Function SerialNum(FDrive: String): String;var Serial:DWord; DirLen,Flags: DWord; DLabel : Array[0..11] of Char;begin Try GetVolumeInformation(PChar(FDrive+’:’),dLabel,12,@

Serial,DirLen,Flags,nil,0); Result := IntToHex(Serial,8); Except Result :=’’;end;

Estado da memória do computador

Adicione um Memo ao Form.

const

cBytesPorMb = 1024 * 1024;

var

M: TMemoryStatus;

begin

M.dwLength := SizeOf(M);

GlobalMemoryStatus(M);

Memo1.Clear;

with Memo1.Lines do begin

Add(Format(‘Memória em uso:

%d%%’, [M.dwMemoryLoad]));

Add(Format(‘Total de memória

física: %f MB’, [M.dwTotalPhys /

cBytesPorMb]));

Add(Format(‘Memória física

disponível: %f MB’, [M.dwAvailPhys

/ cBytesPorMb]));

Add(Format(‘Tamanho máximo

do arquivo de paginação: %f

MB’, [M.dwTotalPageFile /

cBytesPorMb]));

Add(Format(‘Disponível

no arquivo de paginação: %f

MB’, [M.dwAvailPageFile /

cBytesPorMb]));

Add(Format(‘Total de memória

virtual: %f MB’, [M.dwTotalVirtual

/ cBytesPorMb]));

Add(Format(‘Memória

virtual disponível: %f MB’,

[M.dwAvailVirtual / cBytesPorMb]));

end;

end;

Page 29: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010 29

Page 30: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 201030

VerticalHorizontal

Page 31: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010

Page 32: The Club - megazine · Firebird visando uma melhor manutenção dos nossos Bancos de Dados. ... Manipulando Streams no Delphi 2010 Nesse artigo estarei abordando de forma

março 2010