Buscar

mysql

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 32 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

março 2010
março 2010
março 2010 03
Banco de Dados
Stored Procedures e Triggers no 
MySQL
19Autor: Bruno Alcarás
Desafio The Club
.NET
- Dicas Delphi
28
Dicas
- Cruzada
30
Delphi
Banco de Dados
índice
Utilizando componentes ABCr no 
Delphi 2010
Editorial Delphi
10
Espero 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
05
Indo mais além eplorando as 
tabelas de sistema 
Interbase/Firebird14
Novidades do Visual Studio 2010
24
Legenda
Iniciante
Intermediário
Avançado
Autor: Antonio Spitaleri
Autor: Felipe Santos
Autor: Djonatas Tenfen
Autor: Antonio Spitaleri
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 Chefe
marcos@theclub.com.br
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
Internet
http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br 
Informações: info@theclub.com.br
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1 
 theclub_linha2
 theclub_linha3
www.twitter.com/theclubbr
Copyright The Club Megazine 2009
Diretor Técnico
Marcos César Silva
Diagramação e Arte
Vitor M. Rodrigues
Revisão
Tassiane Fileto
Colunistas
Antonio Spitaleri Neto
Bruno Alcarás
Djonatas Tenfen
Felipe Santos
Impressão e acabamento:
GRIL - Gráfica e Editora
Taquarituba-SP - Tel. (14) 3762-1345
Reprodução
A 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.
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
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 TMemorystreamou 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
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(cdsbl
obIMAGEM,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.
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.
março 2010 09
Consultor Técnico The Club.
Sobre o autor
Antonio Spitaleri Neto
antonio@theclub.com.br
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;
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ívele 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, 
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:=TAC
BrECFModelo(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 Contin
uar?’,mtConfirmation,[mbYe
s,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;
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(Appl
ication.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.T
ext),StrToFloat(edtvalorun
itario.Text),
 
StrToFloat(edtdesconto.
Text),edtunidade.Text);
 end;
end;
Botão “Sair”:
procedure Tfrmvenderitem.
btnsairClick(Sender: 
TObject);
var
 sValorpagamento:string;
begin
março 2010 13
 if(MessageDlg(‘Deseja 
finalizar a venda?’,mtConf
irmation,[mbYes,mbNo],0)=m
rYes)then
 begin
 Form1.ACBrECF1.
SubtotalizaCupom;
 sValorpagamento:=In
putBox(‘ACBr’,’Informe o 
valor pago’,’’);
 Form1.ACBrECF1.Efetu
aPagamento(‘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 vendade 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 ACBR
http://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 - ACBrNFe
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/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
antonio@theclub.com.br
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/FIREBIRD
Jurí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.
março 2010 15
Tabela de Sistema Funcionalidade
RDB$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$TRANSACTIONSGrava 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.
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$fields
Set
 rdb$field_length = 60
Where
 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$TRIGGERS
SET
 rdb$trigger_inactive = 1
WHERE
 (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:
março 2010 17
DELETE
 FROM RDB$RELATION_
CONSTRAINTS A
Where
 (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
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$DESCRIPTION
T01P007LJ 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. Trabalhacom 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
felipe.santos@presence.com.br
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.
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 
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 quejá é 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 ROW
BEGIN
 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 ROW
BEGIN
 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
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))
BEGIN
DECLARE 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.82
5.936.-4’,’C’) 
Percebam que o registro ANTONIO foi inse-
rido:
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
bruno@theclub.com.br
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
 
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 projetovai 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.
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
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 
djonatas.tenfen@gmail.com
 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/
março 201028
Dicas DELPHI
Limitar 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(PC
har(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;
março 2010 29
março 201030
VerticalHorizontal
março 2010
março 2010

Continue navegando