Sei sulla pagina 1di 68

SQL73.

indb 1

25/02/2010 14:30:12

10/28/09

8:41 AM

Projeto/
Modelagem

0904HammerBRFullx1a.pdf

6Vkiii
i>`
iviVi`
`i >V`i >`
Vocestcansadodetaxasdedistribuio
emanutenomuitoelevadas?
Vocgostariadeflexibilidadeparaalinharo
modelodelicenciamentodobancode
dadosaoseumodelodenegcios?

Vocnecessitadesuporteadequadoa
diferentesplataformas?

CM

MY

Vocjprecisoudeumacorreoou
novasfuncionalidadesnoprodutoantes
daprximaverso?

CY

CMY

Vocjprecisoudeumnvel
desuportediferenciado?
Vocgostariademelhores
ganhos/margens?

Ento hora de conhecer o:

the right-size Database

>ii- }?Uv>VVUnn
2009FairComCorporation

SQL73.indb 2

25/02/2010 14:30:14

Projeto/
Modelagem

Modelo PrFabricado

Primeiros Passos
em Banco de Dados

[ Mauro Pichiliani ]

Sumrio

14 Conhea na Prtica os Novos Recursos do PostgreSQL 8.4


[ Carlos Eduardo Smanioto ]

22 A Linguagem PL/Java do PostgreSQL Parte 2

Easy

Banco de Dados/ Persistncia

06 Estudos de Caso Projeto de Banco de Dados para Reembolso

[ Clailson de Almeida ]

Dia a Dia

Primeiros Passos em
Banco de Dados

Dia a Dia

Dia a Dia

Desafio SQL

29 Administrando o SQL Server com uma Ferramenta Web


[ Nilton Pinheiro ]

38 Compresso de dados no SQL Server


[ Vladimir Michel Magalhes ]

46 Oracle Performance Diagnostics & Tuning


[ Ricardo Portilho Proni ]

Ol, eu sou o DevMan! Desta pgina em diante, eu estarei lhe ajudando a compreender com ainda
mais facilidade o contedo desta
edio. Ser um prazer contar com
sua companhia! Confira abaixo o
que teremos nesta revista:

54 Usando CDC e Trigger em Auditorias no SQL Server 2008


[ Tulio Rosa ]

62 Desafio SQL
[ Wagner Crivelini ]

Brinde na web desta edio


1) JSP e Apache Derby-Parte 1- Apresentando o aplicativo que ser desenvolvido.

2) JSP e Apache Derby-Parte 2- Realizando a validao do usurio e da senha digitados na tela de login.
3) JSP e Apache Derby-Parte 3- Concluindo a incluso, alterao e excluso de registros.

Vdeos

Para visualizar acesse o link:


http://www.devmedia.com.br/articles/listcomp.asp?keyword=sql73&codigobanca=haloosdt

D
s

Gostou das vdeo aulas? O portal www.devmedia.com.br possui mais de 2 mil vdeo aulas e dezenas de cursos online sobre desenvolvimento de
software! Agora voc pode comprar as vdeo aulas que preferir e fazer sua prpria combinao de vdeos! Saiba mais em www.devmedia.com.br/creditos

D seu feedback sobre esta edio!

Feedback
eu
sobre e
s

edio
ta
SQL73.indb 3

A .NET Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o que voc, leitor, acha da revista!
D seu voto sobre esta edio, artigo por artigo, atravs do link:
www.devmedia.com.br/sqlmagazine/feedback
Para votar, voc vai precisar do cdigo de banca desta edio, que : haloosdt

25/02/2010 14:30:14

Expediente

Editorial
EDITORIAL

O
Ano 7 - 73 Edio 2010 - ISSN 1677918-5 - Impresso no Brasil
Corpo Editorial
Editor Geral
Rodrigo Oliveira Spnola
rodrigo@sqlmagazine.com.br
Sub Editores
Arilo Cludio Dias Neto, Eduardo Oliveira Spnola
e Ricardo Rezende

Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo
para o atendimento ao leitor. Se voc tiver algum
problema no recebimento do seu exemplar ou
precisar de algum esclarecimento sobre assinaturas,
exemplares anteriores, endereo de bancas de
jornal, entre outros, entre em contato com:
Cristiany Queiroz Atendimento ao Leitor
www.devmedia.com.br/mancad/

Capa e Diagramao
Romulo Araujo
romulo@devmedia.com.br

(21) 3382-5038

Reviso e Superviso
Thiago Vincenzo - thiago.v.ciancio@devmedia.com.br
Coordenao Geral
Daniella Costa - daniella@devmedia.com.br
Na Web
www.devmedia.com.br/sqlmagazine/pagina.asp
Distribuio
Fernando Chinaglia Dist. S/A
Rua Teodoro da Silva, 907
Graja - RJ - 206563-900

Kaline Dolabella Gerente de Marketing e


Atendimento
kalined@terra.com.br
(21) 3382-5038

Publicidade
Para informaes sobre veiculao de anncio na
revista ou no site e para fechar parcerias ou aes
especficas de marketing com a DevMedia, entre
em contato com:
Kaline Dolabella
publicidade@devmedia.com.br

Fale com o Editor!


muito importante para a equipe saber o que voc est
achando da revista: que tipo de artigo voc gostaria de
ler, que artigo voc mais gostou e qual artigo voc menos
gostou. Fique a vontade para entrar em contato com os
editores e dar a sua sugesto!
Se voc estiver interessado em publicar um artigo na

revista ou no site SQL Magazine, entre em contato com os


editores, informando o ttulo e mini-resumo do tema que
voc gostaria de publicar:
Rodrigo Oliveira Spnola - Editor da Revista
editor@sqlmagazine.com.br

bservamos atualmente um cenrio em que as organizaes esto cada vez mais dependentes de
sistemas de informaes. Um dos efeitos desta
dependncia o aumento das exigncias sobre requisitos
de qualidade e desempenho. Este ltimo especialmente
crtico em sistemas que manipulam uma quantidade muito grande de informaes.
Melhorar o desempenho de aplicaes pode envolver
diversos fatores. Um deles justamente o ajuste fino dos
bancos de dados onde as informaes so mantidas. Neste contexto, a SQL Magazine destaca nesta edio uma
matria muito interessante intitulada: Oracle Performance Diagnostics & Tuning. O artigo, de autoria de Ricardo
Proni, trata do mtodo de diagnstico de problemas de
desempenho em banco de dados Oracle baseado em
tempo. Tudo isto de forma bastante prtica.
Alm desta matria, a SQL Magazine traz nesta edio
outras matrias muito interessantes envolvendo assuntos
como PostgreSQL, SQL Server, Desafio SQL e Projeto de
Banco de Dados.

Rodrigo Oliveira Spnola


editor@sqlmagazine.com.br

Rodrigo Oliveira Spnola


editor@sqlmagazine.com.br
Editor Chefe da SQL Magazine, WebMobile e
Engenharia de Software Magazine. Doutorando e
Mestre em Engenharia de Software pela COPPE/
UFRJ - o maior centro de ensino e pesquisa em
engenharia da Amrica Latina. Diretor de Operaes
da Kali Software (www.kalisoftware.com).
Autor de diversos artigos cientficos sobre
Engenharia de Software publicados em revistas e
conferncias renomadas, dentro e fora do pas.

Assinatura

Mais contedo SQL por menos!


A revista SQL Magazine parte integrante da assinatura SQL PLUS.
Para mais informaes sobre o pacote SQL PLUS, acesse:
http://www.devmedia.com.br/sqlmagazine/pagina.asp

SQL73.indb 4

25/02/2010 14:30:20

SQL73.indb 5

25/02/2010 14:30:22

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


projeto, anlise ou modelagem de dados

Estudos de Caso Projeto de Banco de Dados


para Reembolso
Modele um banco de dados para um sistema que controla o reembolso de despesas
De que se trata o artigo?

Em que situao o tema til?

Modelagem da estrutura de armazenamento de dados para um sistema de controle dos reembolsos.

O modelo de dados para um sistema que gerencia o


reembolso de despesas de funcionrios em viagens a
trabalho e por conta da empresa. O modelo apresentado neste artigo til para a construo de sistemas
que lidem com o ressarcimento de valores decorrentes
de gastos, alm de gerenciar a aprovao e notificao
do ressarcimento. A partir do modelo sugerido, podese modificar as entidades, atributos e relacionamentos
para adequar a estrutura de acordo com outros tipos
de sistemas que lidem com o reembolso de despesas
e custos de uma empresa.

Para que serve?


Oferecer um modelo inicial para a construo de um
sistema que gerencia o ressarcimento de valores, podendo ser adaptado para diversos outros projetos que
necessitem de um controle de contas e gastos que devem ser justificados.

O
Mauro Pichiliani
pichiliani@uol.com.br

bacharel em Cincia da Computao, mestre pelo ITA (Instituto Tecnolgico de Aeronutica) e MCP, MCDBA e MCTS. Trabalha h
mais de 8 anos utilizando diversos bancos de
dados, como o SQL Server, Oracle e MySQL.
colunista de banco de dados do web site
iMasters. (http://www.imasters.com.br).

6
SQL73.indb 6

s funcionrios e colaboradores
de uma empresa precisam de
diversos recursos para realizarem as suas atividades. Dentre os principais recursos destacam-se pequenas
despesas e gastos com fornecedores
diversos que so comuns em situaes
onde o profissional deve se deslocar para
poder realizar o seu trabalho.
Devido natureza destas despesas e
caractersticas como baixo custo, aleatoriedade e independncia de um fornecedor

especfico, o profissional possui uma certa


liberdade para escolher onde e como estas
despesas sero pagas. Alm disso, este
gasto suportado por algum acordo firmado entre o profissional e a empresa, que
deve indicar como ser o ressarcimento do
que foi gasto por meio de um processo de
reembolso, ou seja, a empresa pagar para
o funcionrio aquilo que ele gastou com o
seu dinheiro desde que o gasto seja justificado e realizado com fins profissionais e
que atendam aos objetivos do negcio.

SQL Magazine - Estudos de Caso Projeto de Banco de Dados para Reembolso


25/02/2010 14:30:24

Projeto

Assim como qualquer outro recurso da empresa que disponibilizado para seus funcionrios e colaboradores, gerenciar
o reembolso dos gastos requer um modelo adequado para
organizar e controlar o caixa, pois caso contrrio h margem
para abusos e uso indevido dos recursos. Alm disso, preciso
armazenar informaes relacionadas aprovao, estimativa,
saldo, histrico, notas fiscais e outras entidades que compem
um modelo de banco de dados utilizado por um sistema de
controle de reembolso.
A partir deste cenrio este artigo apresentar como montar
um modelo de banco de dados que pode ser utilizado por
qualquer empresa que tenha um acordo de reembolso com seus
funcionrios ou colaboradores. O modelo conta com diversas
entidades que abordam os principais aspectos relacionados
ao controle e gerenciamento de despesas em uma empresa
que possui um departamento de vendas cujos funcionrios
precisam viajar para atender aos seus clientes.
Apesar de contemplar diversas situaes, o modelo apresentado neste artigo simples e pode ser estendido para diferentes
tipos de controle de reembolso ou adaptado visando a integrao com o mdulo de contas a pagar e receber de um software
ERP j customizado e implantado na empresa.

Entendendo o cenrio
Para entender como funcionar o controle de reembolso em
uma empresa preciso primeiro delimitar o escopo e escolher um cenrio tpico onde h a utilizao desta forma de
pagamento. Neste artigo vamos considerar uma empresa de
tamanho mdio que possui um departamento de vendas com
50 funcionrios ou colaboradores e que cada funcionrio deste
departamento possui um superior imediato. Neste cenrio
comum encontrar diversas oportunidades de vendas em
locais distantes, ou seja, preciso enviar os vendedores at o
local para uma visita aos clientes, fornecedores ou parceiros.
Na maioria das vezes o transporte controlado e pago diretamente pela empresa, porm as despesas com alimentao,
hospedagem, translado e outros itens devem ser pagos pelo
funcionrio e, dependendo do tipo de acordo de reembolso, a
empresa deve efetuar o ressarcimento dos custos no incio do
prximo ms com prazo mximo de 60 dias.
Antes de comear a detalhar como funcionar o modelo responsvel pelos dados do reembolso preciso definir como ele
funciona no dia a dia e explicar alguns detalhes. O primeiro
ponto a ser entendido diz respeito utilizao do reembolso.
Na empresa de exemplo nem todos os funcionrios possuem
acesso ao programa de reembolso. Isso quer dizer que apenas
aqueles que realmente precisem utilizar esta forma pagamento
tero acesso a ela. Alm disso, preciso formalizar a adeso de
um funcionrio a este recurso atravs de um contrato escrito
e assinado por ambas as partes (empresa e funcionrio) para
evitar problemas legais e tambm para coibir abusos.
Aps a assinatura do contrato um documento com algumas
regras prticas para o reembolso entregue ao funcionrio.
Este documento assume o formato de uma cartilha cujas regras
dizem que o funcionrio deve sempre utilizar o bom senso nos

gastos, procurar o melhor preo, evitar fornecedores e produtos


paralelos, buscar sempre gastos com produtos que possuam
uma boa relao custo/benefcio, evitar exageros e agir com
responsabilidade e prudncia. Esta cartilha tambm indica
alguns limites para certos tipos de gastos como, por exemplo,
valor mximo da diria de hotel, limite com alimentao por
dia, regras sobre a compra de moeda estrangeira e outros.
A regra mais importante da cartilha diz respeito solicitao
de recibos e notas fiscais. A regra simples: todo gasto que no
tiver um recibo, nota fiscal ou comprovante equivalente no
ser reembolsado. O documento que comprova o gasto deve
conter dados obrigatrios como o valor, nome do estabelecimento, CPF ou CNPJ, telefone e informaes de contato e opcionalmente uma assinatura do responsvel. No h excees a
esta regra: se um gasto foi feito sem o documento comprovando
tal ao o funcionrio ter que arcar com o custo da despesa,
porm pode-se trabalhar com documentos digitais. Todos os
gastos esto sujeitos a auditorias internas conduzidas pelo
departamento contbil da empresa. A cartilha tambm deixa
claro que antes do reembolso preciso aprovao do superior
imediato da empresa e tambm do departamento contbil. Por
fim, uma pequena clusula no contrato indica que se houver
abuso ou comportamento de m f o funcionrio estar sujeito
a multas e cancelamento do uso de reembolsos.
Trs modalidades de reembolso foram definidas na empresa
devido aos diversos nveis de hierarquia dentro do departamento de vendas e aos diferentes tipos de despesas necessrias
s viagens dos funcionrios:
1) Recebimento em espcie. Nesta modalidade o funcionrio
deve primeiro elaborar um oramento com os provveis custos
durante a viagem. Assim que este oramento for aprovado o
funcionrio recebe a quantia solicitada em espcie para gastar. Ao final da viagem preciso lanar as notas no sistema e
tambm devolver o valor que sobrou;
2) Carto de crdito da empresa. Nesta modalidade o funcionrio recebe um carto de crdito da empresa e paga todos
os gastos da viagem com este carto corporativo. Opcionalmente pode-se deixar um talo de cheque da empresa com o
funcionrio;
3) Reembolso pleno. Nesta modalidade o funcionrio efetua
os gastos de acordo com os limites estabelecidos na cartilha e
paga as contas com seus prprios recursos. Ao final da viagem
preciso lanar as notas no sistema e aguardar a notificao
de reembolso.
Cada uma das trs modalidades possui um fluxo operacional
diferente e cheio de detalhes que envolvem o cadastramento
da viagem, estimativas de custos, aprovaes, lanamentos de
notas, notificaes e outros. Cada funcionrio do departamento
de vendas pode utilizar qualquer uma das trs modalidades,
desde que tenha assinado o respectivo contrato e que esteja
ciente das normas de utilizao de cada uma das modalidades.
Utilizaremos fluxogramas para simplificar o entendimento das
modalidades iniciando pela Figura 1, que traz o fluxograma da
modalidade Recebimento em espcie. Este tipo de modalidade

Edio 72 - SQL Magazine


SQL73.indb 7

25/02/2010 14:30:24

recomendada para viagens internacionais ou para locais que


j possuem fornecedores conhecidos e com preos tabelados
para os funcionrios da empresa.

Figura 2. Fluxograma da modalidade de reembolso Carto de crdito da


empresa

Figura 1. Fluxograma da modalidade de reembolso Recebimento em


espcie

No incio do fluxograma o funcionrio deve cadastrar a


viagem e incluir uma estimativa razovel de gastos, inclusive
indicando em qual moeda deseja receber a quantia solicitada.
Em seguida preciso aguardar pelas aprovaes do superior
imediato e do departamento de contabilidade. Caso a estimativa no seja aprovada o funcionrio deve alterar a estimativa
e submet-la novamente.
Depois das aprovaes o funcionrio notificado e o sistema
deve verificar se o saldo de viagens anteriores suficiente
para cobrir as despesas desta nova solicitao. Caso positivo,
apenas a diferena entregue em espcie. Caso contrrio, o
valor total entregue para o funcionrio, que efetua gastos
e faz o lanamento das despesas no sistema. Aps o lanamento o funcionrio devolve o dinheiro que sobrou, caso
haja algum, e espera pela aprovao deste lanamento pelo
superior e pela contabilidade. Na hiptese de alguma negao
da aprovao preciso alterar o lanamento de acordo com a
observao do superior ou da contabilidade. Se o funcionrio gastou mais do que foi solicitado ele recebe o reembolso
dentro do prazo estabelecido e notificado pelo sistema. Se
no houver nenhum reembolso o funcionrio apenas recebe
uma notificao informando que o lanamento de despesas
est correto.
A segunda modalidade de reembolso, Carto de crdito da
empresa, parecida com a primeira, porm possui algumas
diferenas. A Figura 2 mostra o fluxograma da modalidade
Carto de crdito da empresa.

8
SQL73.indb 8

A modalidade de reembolso Carto de crdito da empresa


utilizada nas situaes onde os gastos so grandes ou podem
apenas ser feitos com o carto de crdito, como compras pela
internet. Apenas certos funcionrios da hierarquia podem
utilizar esta modalidade como, por exemplo, coordenadores,
gerentes, diretores, membros do conselho presidencial e vicepresidentes. No incio do fluxograma o funcionrio deve indicar a viagem ou o motivo pelo qual est requisitando o carto
de crdito corporativo. Nota-se que logo em seguida ele j
recebe o carto sem precisar de uma aprovao, pois de acordo
com o seu cargo o sistema j reconhece que este funcionrio
tem um cargo de confiana na hierarquia e responsvel o
suficiente para receber o carto. Em seguida o funcionrio faz
os gastos e lana as despesas junto com os comprovantes. Aps
o lanamento preciso seguir o mesmo fluxo de aprovao
da modalidade Recebimento em espcie, ou seja, preciso a
aprovao do superior e do departamento de contabilidade.
Se houver algum reembolso feito em dinheiro este deve ser
pago e notificado ao funcionrio. Por fim, preciso devolver
o carto corporativo para a contabilidade, a no ser em casos
especiais onde o carto fica alocado de forma permanente com
o funcionrio. Alternativamente pode-se entregar um talo de
cheques da empresa para os funcionrios ao invs do carto de
crdito, porm o fluxo operacional continua o mesmo.
A terceira e ltima modalidade de reembolso, cujo nome
Reembolso pleno, a modalidade mais comum nas empresas. Geralmente utiliza-se esta forma de reembolso quando
as despesas no so grandes e a viagem curta. Alm disso,
este tipo de modalidade diminui a probabilidade de riscos
de abuso por parte dos funcionrios, uma vez que eles que
devem pagar os custos primeiro para depois receber o valor
na forma de reembolso. A Figura 3 apresenta o fluxograma
da modalidade Reembolso pleno.
O fluxograma da modalidade de reembolso Reembolso pleno
bem parecido com as outras modalidades. Inicialmente o funcionrio cadastra a viagem e indica que utilizar a modalidade
Reembolso pleno. Aps a aprovao do superior e do departamento de contabilidade o funcionrio recebe uma notificao,
efetua os gastos e faz o lanamento das notas e comprovantes.

SQL Magazine - Estudos de Caso Projeto de Banco de Dados para Reembolso


25/02/2010 14:30:25

Projeto

Figura 3. Fluxograma da modalidade de reembolso Reembolso pleno

Aps o lanamento preciso que o superior e o departamento


de contabilidade aprovem o lanamento e as despesas para s
ento efetuar o reembolso e notificar o funcionrio.
Os fluxogramas das trs modalidades de reembolso so bem
parecidos e contm pequenas diferenas entre si, o que indica que possvel juntar os trs fluxogramas em apenas um.
Entretanto, para tornar mais didtica a explicao dos fluxos
que representam os principais passos de cada modalidade,
optou-se por apresentar os fluxogramas de forma separada.
Recomenda-se tambm que a especificao do uso de cada
modalidade de reembolso seja representada com artefatos de
software mais formais, tais como diagramas de Casos de Uso e
diagramas de Estados, pois desta maneira a equipe do projeto
contar com mais artefatos para o entendimento, modelagem,
especificao e documentao do sistema.

Modelagem das entidades


A partir da explicao de funcionamento do reembolso descrita na seo anterior podemos comear a modelagem indicando quais so as principais entidades do modelo Entidade
Relacionamento. A Figura 4 apresenta uma verso inicial do
modelo com os nomes de 14 entidades relevantes para o banco
de dados que gerenciar as modalidades de reembolso.

Esta delimitao quer dizer que preciso identificar e abstrair


certas caractersticas dos cenrios de modo a melhorar o modelo para que ele represente a realidade apenas nos aspectos que
fazem sentido para o banco de dados relacionado ao contexto
do reembolso.
Na Figura 4 podemos notar que as entidades FUNCIONRIOS e CARGOS fazem parte do modelo, mas no modelo
final no as detalharemos. Estas entidades geralmente j esto presentes em sistemas de RH (Recursos Humanos) ou de
controle de acesso e no faz muito sentido repeti-las no banco
de dados. Devido a isso, o modelo do sistema de reembolso
vai utilizar apenas chaves estrangeiras para a entidade de
funcionrio e no conter nenhuma relao com a entidade de
cargos, pois a partir de um funcionrio possvel obter o seu
cargo. Esta abstrao, ou seja, deixar de fora o detalhamento
destas duas entidades, apresenta um refinamento no modelo,
focando no objetivo e eliminando elementos que j existem em
outro sistema. Outro detalhe importante que os funcionrios
que devem aprovar algo, sejam superiores ou funcionrios da
contabilidade, so todos considerados funcionrios j armazenados na entidade FUNCIONRIOS.
Outra entidade que tambm pode ficar de fora do modelo
final a entidade FORNECEDORES, pois apesar de ser importante contar com algumas informaes sobre fornecedores,
raramente o mesmo fornecedor ser cadastrado devido
aleatoriedade dos locais de despesas. Os dados relevantes do
fornecedor sero armazenados em uma entidade que contm
os comprovantes. Alis, o levantamento inicial identificou as
entidades NOTA FISCAL, COMPROVANTES e RECIBOS,
que detalham a forma na qual o funcionrio comprova seus
gastos. Para simplificar, o modelo final contar apenas com a
entidade COMPROVANTES, que ter um atributo responsvel por indicar qual o tipo do comprovante. Outra abstrao
do modelo inicial diz respeito s entidades CARTES e
CHEQUES, que representam os cartes de crdito e tales
de cheque da empresa. Estas duas entidades sero transformadas em apenas uma entidade que armazena o recurso de
pagamento ao invs de duas entidades separadas.
A primeira entidade que detalharemos a principal entidade
do nosso modelo: VIAGEM_FUNCIONARIO. Esta entidade
utilizada em qualquer uma das trs modalidades de reembolso,
pois a atividade cadastrar viagem aparece nos trs fluxogramas

Nota do DevMan
Figura 4. Quatorze entidades iniciais do modelo de controle de reembolso

As entidades apresentadas na Figura 4 representam apenas


o levantamento inicial do que ser modelado, ou seja, a partir da explicao das modalidades de reembolso criaram-se
diversas entidades. A partir dessas entidades o modelo ser
construdo por sucessivos refinamentos e melhorias. Porm,
importante delimitar o escopo e identificar at que ponto as
entidades modeladas fazem parte ou no do banco de dados.

Atributo flag: Existem diversas definies do que um atributo flag. A mais


comum diz que um atributo flag aquele que permite apenas dois tipos de valores: 0 ou 1, tambm referenciados como SIM/NO ou VERDADEIRO/FALSO (TRUE/
FALSE). Geralmente atributos flag so utilizados para modelar caractersticas ou
aspectos binrios que podem existir ou no sem nenhum tipo de meio termo. A
implementao depende do banco de dados em questo, mas comum o uso do
tipo de dados booleano onde apenas 0 ou 1 so utilizados para armazenar os valores de atributos do tipo flag.

Edio 72 - SQL Magazine


SQL73.indb 9

25/02/2010 14:30:25

descritos na seo anterior. Esta entidade possui um atributo


com o identificador sequencial, que a chave primria da
entidade, e um atributo para armazenar o identificador do
funcionrio que se relaciona a uma entidade j existente em
um sistema de RH ou de acesso que no ser modelada para
evitar duplicidade no banco de dados. Da forma que a entidade
VIAGEM_FUNCIONARIO foi modelada preciso cadastrar
uma nova viagem para cada funcionrio, pois a viagem ser
associada com o reembolso que individual. Uma tela do
sistema pode facilitar a entrada de dados apresentando apenas uma vez os campos para digitao dos dados da viagem
e apresentar uma planilha ou grid para a indicao de vrios
funcionrios para uma mesma viagem.
A entidade tambm contm atributos para indicar a data de
partida e estimativa de data de retorno, a descrio do local
para onde o funcionrio est indo e tambm um atributo que
permite a entrada de um texto longo para descrever o motivo
da viagem, cliente ou parceiro a ser visitado, a companhia de
viagem e outros detalhes relevantes.
Como preciso a aprovao tanto do superior imediato como
do departamento de contabilidade, a entidade possui dois
atributos para armazenar o status da aprovao. Este status
armazenado por meio de atributos flag que geram o status
atual da solicitao da viagem, ou seja, indicam se a viagem
no foi aprovada (valor 0) ou se foi aprovada com sucesso (valor
1). Nota-se que a partir do contedo destes atributos o sistema
automaticamente pode informar para o usurio qual o status
da viagem e por isso no foi modelado um atributo especfico
para indicar o status como, viagem aprovada, pendente ou
negada. Tambm preciso incluir atributos para indicar quais
so os funcionrios que fazem as aprovaes, ou seja, quem o
funcionrio superior e quem o funcionrio do departamento
de contabilidade que far a aprovao.
Por fim, a entidade possui um atributo para armazenar a estimativa de gastos da modalidade Recebimento em espcie, um
atributo de texto livre e longo para informaes sobre o transporte
(nmero da passagem area, horrio de partida e chegada, etc.) e
tambm qual ser a moeda utilizada no destino da viagem.
Quando o funcionrio est comeando a preencher os detalhes da viagem ele j deve indicar qual ser a modalidade de
reembolso utilizada. Para armazenar esta informao preciso
criar no modelo a entidade MODALIDADE_REEMBOLSO,
que contm um identificador nico e atributos para armazenar
o nome da modalidade (Recebimento em espcie, Carto de
crdito da empresa ou Reembolso pleno) e observaes de
cada modalidade. Alm disso, preciso adicionar na entidade
VIAGEM_FUNCIONARIO um atributo para indicar o relacionamento com a entidade MODALIDADE_REEMBOLSO. A
Figura 5 apresenta as entidades MODALIDADE_REEMBOLSO
e VIAGEM_FUNCIONARIO junto com o detalhamento de seus
atributos em um modelo entidade relacionamento parcial.
A prxima entidade a ser modelada diz respeito notificao do funcionrio. Esta notificao deve ser realizada
de acordo com os contatos individuais de cada funcionrio, que so modelados em uma entidade chamada

10
SQL73.indb 10

CONTATOS_FUNCIONARIO. Esta entidade conter um


identificador nico do contato, uma chave estrangeira para
a entidade de funcionrios, o nmero de telefone, o endereo
de e-mail e tambm endereos na rede de microblogs, como
Twitter e um endereo para a rede social Orkut. Outras formas
de notificao podem ser utilizadas de acordo com as formas
de entrar em contato com o funcionrio, porm este modelo
apenas ir considerar as formas de contato descritas acima.

Figura 5. Entidades VIAGEM_FUNCIONARIO e MODALIDADE_REEMBOLSO


do modelo de controle de reembolso

Para associar uma forma de contato do funcionrio com uma


viagem preciso criar uma nova entidade, que se chamar
NOTIFICA_FUNCIONARIO. Esta entidade contm o identificador da viagem e o identificador do contato. Alm disso,
foram criados atributos flags que indicaro quais contatos sero
utilizados para notificar a aprovao da viagem e o reembolso
das despesas, que podem assumir a forma de um telefonema,
um e-mail, uma mensagem SMS, uma mensagem do tipo direct
no Twitter ou uma mensagem na rea pblica (scrap) ou privada
(depoimento) do Orkut, dependendo do endereo cadastrado
nesta rede social. A Figura 6 apresenta o modelo parcial com
as entidades VIAGEM_FUNCIONARIO, CONTATOS_FUNCIONARIO e NOTIFICA_FUNCIONARIO.
Aps a modelagem das entidades responsveis pela notificao
do funcionrio preciso indicar como os cartes de crdito e
tales de cheque devem ser associados a um funcionrio. A
entidade RECURSO_PAGAMENTO conter um identificar
nico, o nome do recurso (carto, cheque, travellers check, etc.),
uma chave estrangeira para a entidade de funcionrios que
indica com quem este recurso est atualmente, um atributo
indicando o limite mximo de gasto deste recurso, um identificador interno (quatro ltimos dgitos do carto ou nmero do
cheque) e tambm um atributo para observaes de uso deste

SQL Magazine - Estudos de Caso Projeto de Banco de Dados para Reembolso


25/02/2010 14:30:25

Projeto

recurso de pagamento. Nota-se que as instncias da entidade


RECURSO_PAGAMENTO so associadas ao funcionrio e no
a uma viagem e que cada vez que o recurso trocar de funcionrio
preciso alterar o atributo ID_RESPONSAVEL_ATUAL.
A seguir devemos modelar a entidade que armazena o tipo
de comprovante, que recebe o nome TIPO_COMPROVANTE.
Esta entidade possui uma chave primria no atributo ID_TIPOCOMPROVANTE e contm atributos para o nome do comprovante (nota fiscal, recibo, comprovante, etc.) e um atributo flag
que indica se este comprovante possui valor fiscal ou no.
O lanamento dos comprovantes de gastos nas viagens
do funcionrio ser armazenado na entidade COMPROVANTES. Esta entidade contm um identificador nico
(ID_GASTO) do gasto, um atributo que chave estrangeira
para a entidade TIPO_COMPROVANTE (ID_TIPOCOMPROVANTE), um atributo que chave estrangeira para
a entidade VIAGEM_FUNCIONARIO (ID_VIAGEM), e
atributos para armazenar o CNPJ ou CPF, nome e telefone de contato do fornecedor, armazenados nos atributos
CNPJ, CPF, NOME_CONTATO, DATA e TEL_CONTATO,
respectivamente. A entidade tambm possui atributos para
armazenar a data do comprovante (DATA_COMRPOVANTE),
descrio para indicar circunstncias, detalhes e motivo do
gasto (DESC_GASTO), qual a forma e condies de pagamento
(FORMA_PAGAMENTO) e um atributo flag para indicar se o
gasto foi para se obter um servio ou um produto. A Figura 7
apresenta o modelo parcial com as entidades j modeladas
anteriormente e as novas entidades RECURSO_PAGAMENTO, COMPROVANTES e TIPO_COMPROVANTE.
A ltima entidade a ser modelada armazenar as informaes
a respeito do reembolso da viagem. Esta entidade conter uma
chave primria no atributo ID_REEMBOLSO e uma chave estrangeira no atributo ID_VIAGEM, que far o relacionamento
com a entidade VIAGEM_FUNCIONARIO. A entidade conta
tambm com um atributo para armazenar o valor do reembolso,

Figura 6. Entidades VIAGEM_FUNCIONARIO, NOTIFICA_FUNCIONARIO


e CONTATOS_FUNCIONARIO adicionadas ao modelo de controle de
reembolso

o saldo do funcionrio no momento em que o reembolso for


feito, as informaes sobre os identificadores dos usurios que
aprovam (superior e contabilidade) e os atributos flags para
identificar o status das aprovaes. Assim que o reembolso for
aprovado preciso armazenar a data do reembolso, o nmero
do cheque caso esta seja a forma de pagamento escolhida ou as
informaes bancrias para pagamento (banco, agncia e conta).
Por fim, qualquer observao a respeito do pagamento deve ser
indicada em um atributo de texto livre. A Figura 8 apresenta o
diagrama com o modelo de banco de dados final para o sistema
de controle de reembolso de despesas.

Figura 7. Modelo anterior com a adio das entidades RECURSO_PAGAMENTO,


COMPROVANTES e TIPO_COMPROVANTE

Edio 72 - SQL Magazine


SQL73.indb 11

11

25/02/2010 14:30:26

Figura 8. Modelo final contendo todas as entidades do banco de dados para controle de reembolsos

Nota do DevMan

Nota do DevMan

12
SQL73.indb 12

de novas entidades relacionadas com o reembolso de despesas


de uma empresa e tambm para outros fins, como o controle
de gastos com matria prima, ingredientes, gerenciamento de
conta de materiais para projetos e outros tipos de situaes
que necessitem de ressarcimento posterior dos gastos.
Referncias
Artigo Anlise de Requisitos com Casos, escrito pelo Kleber Xavier e publicado na edio
nmero 49 da revista Java Magazine.

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/sqlmagazine/feedback

Feedback
eu
sobre e
s

Este artigo mostrou como modelar as principais entidades de


um sistema que controla o reembolso de despesas dos funcionrios de uma empresa durante viagens. O modelo apresentado
foi gerado a partir de um cenrio tpico onde funcionrios/
colaboradores precisam viajar para atender clientes, parceiros,
ou fornecedores e efetuam gastos durante esta viagem. Um
modelo de dados foi elaborado a partir dos fluxogramas das trs
modalidades de reembolso utilizadas pela empresa. Este modelo
contm entidades, atributos e relacionamentos que representam
viagens, gastos, comprovantes, aprovaes, notificaes, recurso
de pagamento e outros aspectos relacionados ao processo de
reembolso de acordo com as modalidades especificadas.
O modelo de dados foi apresentado de acordo com a modelagem de cada uma das entidades e seus relacionamentos.
Apesar de ser apenas uma sugesto, as principais entidades
do cenrio descrito foram contempladas pelo modelo de dados, que pode servir como ponto de partida para a modelagem

D
s

Concluso

Travellers checks: O traveller check, ou cheque de viagens, uma forma cmoda e


segura de levar dinheiro em viagens internacionais. aceito em hotis e em diversos
estabelecimentos comerciais em todo o mundo, como lojas e restaurantes, e tambm
pode ser facilmente trocado pelo dinheiro local em instituies financeiras ou postos
de cmbio. Os estabelecimentos comerciais, no entanto, podem no aceitar este tipo de
pagamento, forando a troca de um traveller check pela moeda local em uma casa de
cmbio ou instituio financeira. O traveller check requer a assinatuda do portador, pode
ser em dlar, euro ou outras moedas e aceito prinicipalmente nos Estados Unidos e
raramente em pases cuja moeda local no seja o dlar. Neste caso, ser preciso realizar
uma operao de cmbio, como compra de moeda em espcie.

edio
ta

Software ERP: ERP (do ingls Enterprise Resource Planning) so os sistemas de informaes que integram todos os dados e processos de uma organizao em um nico
sistema. A integrao pode ser vista sob a perspectiva funcional (sistemas de finanas,
contabilidade, recursos humanos, fabricao, marketing, etc.) e sob a perspectiva sistmica (sistema de processamento de transaes, sistemas de informaes gerenciais,
sistemas de apoio a deciso, etc.). Estes sistemas envolvem a parte administrativa da
empresa e geralmente so de misso crtica, pois envolvem processos fundamentais
para o funcionamento da empresa.

SQL Magazine - Estudos de Caso Projeto de Banco de Dados para Reembolso


25/02/2010 14:30:27

Projeto

Modstia parte, sua


melhor opo para
se destacar no mercado!
A Escola Superior da Tecnologia da
Informao oferece as melhores
opes em cursos, formaes,
graduaes e ps-graduaes para
profissionais de desenvolvimento
e programao.
So programas voltados para a
formao de profissionais de elite,
com aulas 100% prticas, corpo
docente atuante no mercado,
acesso mais atualizada biblioteca
de TI do Rio, laboratrios equipados
com tecnologia de ponta, salas de
estudo e exames.

PS- GRADUAO

Engenharia de Software:
Desenvolvimento Java
Engenharia de Software:
Desenvolvimento .NET
GRADUAO

Engenharia de Computao
Anlise e Desenv. de Sistemas
F ORMAES

Desenvolvedor Java
Desenv. Java: Sist. Distribudos
Gestor de TI
Desenvolvedor Web .NET 2008
MCITP Server Administrator
SQL Server 2008

r/esti
Acesse nosso site e conhea todos os nossos programas: www.infnet.edu.br/esti
TURMAS
NO RIO DE
JANEIRO
www.infnet.edu.br - cursos@infnet.edu.br - Central de Atendimento: (21) 2122-8800

EDUCAO SUPERIOR ORIENTADA AO MERCADO


Edio 72 - SQL Magazine
SQL73.indb 13

13

25/02/2010 14:30:27

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Conhea na Prtica os Novos Recursos do


PostgreSQL 8.4
Projete um Sistema de Companhia Area com o novo PostgreSQL

objetivo deste artigo modelar


e projetar o sistema para uma
companhia area que desejar
um maior controle de seus vos, funcionrios e bilhetes emitidos. Para isso,
sero demonstradas algumas das novidades da verso 8.4 do PostgreSQL,
cuja verso saiu no incio de Julho de
2009. Dentre as novidades, podemos
citar o windowing functions, consultas
recursivas e criao de valor padro em
parmetros de funo.

Novas Funcionalidades do PostgreSQL


Carlos Eduardo Smanioto
www.datapower.com.br
carlos.smanioto@datapower.com.br

Diretor da Data Power Technology, uma empresa de consultoria e Business Soluctions


na rea de T.I. Formado em Cincias da
Computao, atuando a mais de 10 anos
com banco de dados PostgreSQL e segurana da informao. Possui em seu currculo
diversos artigos, palestras realizadas. Trabalha com projetos. NET e JAVA adotando banco de dados Oracle/PostgreSQL e prestao
de servio como por exemplo, treinamento
IN-COMPANY.

14
SQL73.indb 14

Antes de iniciarmos a modelagem e


projeto do sistema de uma companhia
area, precisamos conhecer alguns dos
novos recursos disponibilizados pela
nova verso 8.4 do PostgreSQL, que
ser utilizado para o projeto do banco
de dados deste sistema.
O PostgreSQL 8.4 possui mais de 293
novidades, muitas mudanas para deixar o SGDB mais competitivo contra outros SGBDs como o SQL Server e Oracle
no que diz respeito a funcionalidades,
outras melhorias buscam praticidade,

De que se trata o artigo?


O artigo demonstra o projeto de um sistema de
uma companhia de passagem area, apresentando algumas das novas funcionalidades do
PostgreSQL 8.4

Para que serve?


Atravs deste artigo, o leitor ter uma viso prtica
das decises de projeto a serem tomadas na modelagem de um sistema que gerencia tarefas de uma
companhia area, e ainda uma viso ampla sobre
a nova verso do PostgreSQL, onde no apenas so
apresentadas as principais funcionalidades, mas
tambm foi ensinado como explor-las.

Em que situao o tema til?


Este artigo ajuda o DBA PostgreSQL na modelagem de sistemas com caractersticas similares ao projeto utilizado como estudo de caso,
e ainda auxilia a equipe de desenvolvimento a
decidir qual o momento certo de realizar um
upgrade de verso do PostgreSQL.

segurana e velocidade. Neste momento,


iremos apresentar algumas que mais
chamam a ateno. Vamos conhec-las?
Elas esto citadas na Tabela 1.

SQL Magazine - Conhea na Prtica os Novos Recursos do PostgreSQL 8.4


25/02/2010 14:30:28

postgresql

O arquivo postgresql.conf
Para entender melhor os novos recursos do PostgreSQL,
precisamos conhecer alguns novos elementos includos no
arquivo de configurao do PostgreSQL: o postgresql.conf.
lgico que o postgresql.conf continua basicamente o
mesmo, exceto que ele se tornou maior, ele esta agora 65
linhas a mais. Um dos principais motivos para isso a configurao de certificado SSL, nova feature do PostgreSQL
que permite a utilizao de um certificado de segurana,
deixando assim o sistema mais seguro. Existem tambm
novidades no gerenciamento de I/O, conforme apresentado
na Listagem 1.
Esta configurao permite ao PostgreSQL realizar um
nmero n de operaes de I/O no disco por sesso. A
documentao sugere que este valor seja o nmero de HDs
disponvel para o PostgreSQL em um RAID do tipo 0 ou 1.
Funcionalidades

Caso seja RAID 5, contar os HD desconsiderando o HD que


esta separado para ser paridade. Por exemplo, em um RAID
0 ou 1 ou RAID 0+1, se o sistema possuir 4 HDs, o valor de
effective_io_concurrency ser 4; mas em um RAID 5, se forem
4 HDs, o valor ser 3.
Tambm foi adicionado configurao o seguinte trecho
apresentado na Listagem 2.
Estas configuraes dizem ao Vacuum a idade em transaes.
Quando os valores em idade transacional so atingidos pelo
sistema, o VACUUM reinicia estes valores dentro da tabela.
A cada nova transao, esta idade acrescida. uma espcie
de sequence das transaes.
Em resumo, esta nova verso est demonstrando a vontade
da comunidade PostgreSQL em realmente manter o elefante
como uma soluo para o mercado no somente pelo quesito
custo, mas pelo quesito desempenho e funcionalidades.
O que isso faz

Windowing Functions

As Funes de Janelas ou agregados de janelas so um conjunto de functions que permitem que voc faa operaes como count, sum, e rank sobre
(over) um subconjunto de seus dados, isso sem agrupamento. Com as windows functions, podemos gerar um relatrio que demandava vrias consultas
com uma nica consulta. Estas windows functions tambm ampliam o suporte do PostgreSQL para aplicaes do tipo B.I. (Business Intelligense). Veremos
mais sobre como isso funciona mais adiante.
Expresses de tabelas comuns e consultas Conhecidas como CTEs (Common Table Expressions and Recursive Queries). O Principal uso da CTEs possibilitar subconsultas complexas sem criar tabelas
recursivas
temporrias e principalmente permitir a criao de consultas recursivas. Isso foi uma importante implementao para o PostgreSQL, pois esta capacidade
j existia no SQL Server desde a verso 2005.
ALTER SEQUENCE, VIEW, DATABASE
Foi melhorada a lgica do comando ALTER para cada tipo de objeto. Por exemplo, agora possvel reiniciar um sequence para voltar ao valor inicial atravs
de um simples ALTER SEQUENCE RESTART.
possvel agora adicionar novas colunas em uma view diretamente pelo comando ALTER VIEW ADD COLUMN
O Alter tambm ganhou poderes no DATABASE. Agora podemos mover fisicamente os objetos de um Banco de Dados para um novo tablespace. Isso
significa que em caso de falta de espao, via ALTER podemos mover uma tabela para outra partio, unidade, enfim, um lugar com espao disponvel.
Parmetros DEFAULT e Variveis para Functions possvel agora criar um nmero varivel de argumentos para uma function. Alm disso, possvel definir um valor padro para argumento em funes.
Assim, quando a funo for invocada e no passar argumentos para ele, o valor padro assume como argumento. Estas mudanas facilitam a migrao do
SQL Server e Sysbase para PostgreSQL.
Restaurao paralela
A ferramenta pg_restore agora pode restaurar dados e criar objetos paralelamente, ou seja, enquanto esta criando a tabela2, ele est subindo os dados da
tabela1. Isso gerou um aproveitamento melhor do hardware.
Segurana por Coluna
possvel nesta verso atribuir no somente segurana na Tabela (GRANTs/REVOKE) mas tambm por coluna.
Configurao Regional (locale) por DB
Melhoria de desempenho com ndices hash
Semi-joins e Anti-joins

Configurao automtica para o Free Space Map

Editor de Function

A configurao locale pode ser configurada individualmente por DB, ou seja, podemos ter um PT_BR.UFT8 para um banco e ISO para outro. Nas verses
anteriores, o LOCALE era configurado por cluster; ou na criao do cluster atravs com comando initdb ou via postgresql.conf.
ndices hash do PostgreSQL agora localizam linhas simples mais rpido do que os ndices B-Tree, e tornaram-se teis para a indexao de campos
identificao em alguns bancos de dados.
O Sistema agora consegue escolher o melhor mtodo de execuo para subconsultas semanticamente semelhantes. Desta forma, o desenvolvedor no
precisa verificar o que seria mais rpido: t1.c1 = t2.c2 ou t2.c2 = t1.c1 ?
Exemplo de Semi-join:
SELECT D.deptno, D.dname FROM dept D
WHERE EXISTS
(
SELECT 1 FROM emp E
WHERE E.deptno = D.deptno
)
ORDER BY D.deptno
Fim da configurao de max_fsm_page. Nas verses anteriores, o PostgreSQL usava a Shared Memory para alocar um mapa com informaes de pginas
vazias, ou seja, lugares que podem ser ocupados com novos registros, por exemplo aps um delete. Este Mapa agora dinmico e fica no prprio HD. A
grande vantagem disso reduzir I/O, ou seja, aumenta o desempenho da aplicao.
Agora o psql possui o /ef nome_da_function que abre um editor com a function para ser editada.

Tabela 1. Algumas das 300 novas funcionalidades da srie 8.4

Edio 72 - SQL Magazine


SQL73.indb 15

15

25/02/2010 14:30:28

Listagem 1. postgresql.conf pedao do novo arquivo conf


139. # - Asynchronous Behavior 140.
141. #effective_io_concurrency = 1

# 1-1000. 0 disables prefetching

Listagem 2. postgresql.conf pedao do novo arquivo conf


400. #autovacuum_freeze_max_age = 200000000
forced vacuum
425. #vacuum_freeze_min_age = 50000000
426. #vacuum_freeze_table_age = 150000000

# maximum XID age before

Vamos agora demonstrar algumas possibilidades desta nova


verso com a incorporao do SQL ANSI 2008.

Projetando o sistema de uma companhia area: a


Brazilian Airlines
Nosso projeto modelo consiste em desenhar um banco de
dados para a nossa fictcia companhia rea que surgiu no
Brasil, a BRAZILIAN AIRLINES. Esta companhia fez um
estudo tecnolgico e resolveu adotar o PostgreSQL como
banco de dados para o sistema que esto desenvolvendo.
A princpio, o sistema ir precisar controlar os funcionrios
e gerar um MAPA de vo com possibilidade de escalas e
logicamente um controle de seus avies com informaes
sobre quantidade de passageiros, para que possa vender os
bilhetes para um determinado vo sem vender passagem
fora do limite.
Por isso, o sistema precisa:
1) O pessoal do RH quer saber informaes sobre o salrio
dos departamentos;
2) Exibir na tela os vos que os Engenheiros de vo
criaram;
3) Na venda do Bilhete, ter um controle de venda dentro do
limite do avio selecionado para um vo.
Ao longo deste artigo, veremos como atender s demandas
requisitadas para o sistema em questo, demonstrando novas
funcionalidades do PostgreSQL 8.4. Para comear, vamos
conhecer a configurao das tabelas, conforme as Figuras 1
e 2 nos mostra.

Figura 2. Tabela funcionario e auxiliar

Na Figura 1, estamos dizendo que o vo o elemento principal do modelo, atravs da tabela voos, pois s podemos
vender uma passagem area se existir um vo cadastrado.
Isso tambm justifica a coluna voo_num na tabela bilhete.
Observe na tabela voos a ltima coluna, qtd_disponivel: esta
coluna contm a quantidade de passagens que podem ser
vendidas para cada vo cadastrado. Alm disso, um vo s
pode existir se existir um avio disponvel para aquele vo,
por isso relacionamos a tabela voos com a tabela aviao.
Na Figura 2, ns atribumos os funcionrios (tabela funcionario) ao seu respectivo departamento (tabela departamento).
um relacionamento N para 1.

Povoando o Banco de Dados


As Listagens 3 a 7 apresentam cdigos SQL que iremos seguir
em nosso projeto para preencher as tabelas criadas com dados
que sero usados para demonstrar as novas funcionalidades
disponibilizadas no PostgreSQL 8.4.

Requisio 1) O pessoal do RH quer saber informaes


sobre o salrio dos departamentos
Na Brazilian Airlines, existem 8 departamentos com diversos
funcionrios vinculados a estes departamentos. O departamento de Engenharia de vo aloca os pilotos, co-pilotos,
aeromoas que ganham os maiores salrios da companhia. Os
chefes de cada departamento ganham um salrio diferenciado
por ocupar um cargo de maior responsabilidade.
Neste exemplo, a diretoria da empresa quer saber a mdia de
salrios dos departamentos. Como o departamento de computao adotou o PostgreSQL 8.4, os analistas podem solucionar
a solicitao da diretoria usando uma Windows Function (ver
Nota DevMan 1).
Vamos ver como a Windowing Function pode ser muito til na
hora de gerar um relatrio. Iremos realizar uma consulta que ir
nos mostrar o salrio do funcionrio, departamento pertencente

Nota do DevMan 1
Detalhando as Windows Functions
As Windowing functions so uma implementao de suma importncia introduzida na linguagem SQL:2003 (reviso realizada em 2003 na SQL ANSI). Esta
reviso da SQL permite funes de agregao sobre os dados. Estas funcionalidades permitem no somente ao PostgreSQL agradar aos desenvolvedores do SQL
Server e Oracle, como tambm veio para facilitar ao desenvolvedores de muitos
anos PostgreSQL.
Figura 1. Tabela voos e as tabelas auxiliares

16
SQL73.indb 16

SQL Magazine - Conhea na Prtica os Novos Recursos do PostgreSQL 8.4


25/02/2010 14:30:28

postgresql

e a mdia por departamento de uma nica vez de uma forma extremamente simples! Tal consulta est descrita na Listagem 8.
A consulta ir gerar a mdia salarial por departamento, mas
como funciona isso? Antes da Windowing Functions, para gerar
um resultado que iremos ver a seguir, precisaramos usar uma
consulta muito complexa agrupada com GROUP BY, talvez
at mesmo um subselect ou outras tcnicas, isso dependeria
de como o desenvolvedor enxergasse a soluo. Mas agora,
quando usamos funes de agrupamento (como AVG, por
exemplo) podemos definir o mecanismo deste agrupamento
com a sintaxe OVER (PARTITION BY tabela). Veremos na
Listagem 9 como seria a sintaxe em portugus do cdigo SQL
apresentado na Listagem 8, para ficar mais claro.
A Windowing Functions s surtiu efeito porque existe um relacionamento entre as tabelas funcionrio e departamento, mas
podemos perceber claramente o vnculo entre os comandos
AVG() e o OVER(Partition By) que gera o agrupamento em
funo da tabela especificada. A consulta da Listagem 8 gera
o resultado apresentado na Figura 3.

Listagem 3. Inserindo dados na tabela aviao


INSERT INTO aviao (aviao_num, aviao_modelo, aviao_fabricante,
aviao_ultima_revisao, aviao_habilitado_vo, qtd_passageiros)
VALUES (A330, Boing Airbus, 2004, 2009-05-10, true, 400);
INSERT INTO aviao (aviao_num, aviao_modelo, aviao_fabricante,
aviao_ultima_revisao, aviao_habilitado_vo, qtd_passageiros)
VALUES (EMB-120, EMBRAER EMB-120 Brasilia, 1983, 2009-0813, true, 250);
INSERT INTO aviao (aviao_num, aviao_modelo, aviao_fabricante,
aviao_ultima_revisao, aviao_habilitado_vo, qtd_passageiros)
VALUES (ERJ-145, EMBRAER ERJ-145, 1995, 2009-10-27,
true, 350);

Listagem 4. Inserindo dados na tabela voos


INSERT INTO vos (vo_num, cidade_partida, cidade_chegada, hora_
saida, hora_chegada, aviao_num, qtd_disponivel)
VALUES (BZ-2010001, RIO DE JANEIRO, SAO PAULO, 07:00:00,
08:00:00, EMB-120, 245);
INSERT INTO vos (vo_num, cidade_partida, cidade_chegada, hora_
saida, hora_chegada, aviao_num, qtd_disponivel)
VALUES (BZ-2010004, RIO DE JANEIRO, BAURU, 07:00:00,
10:00:00, ERJ-145, 345);
INSERT INTO vos (vo_num, cidade_partida, cidade_chegada, hora_
saida, hora_chegada, aviao_num, qtd_disponivel)
VALUES (BZ-2010002, SAO PAULO, BAURU, 08:30:00,
09:30:00, EMB-120, 248);
INSERT INTO vos (vo_num, cidade_partida, cidade_chegada, hora_
saida, hora_chegada, aviao_num, qtd_disponivel)
VALUES (BZ-2010003, SAO PAULO, GOIANIA, 09:00:00,
14:00:00, A330, 398);
INSERT INTO vos (vo_num, cidade_partida, cidade_chegada, hora_
saida, hora_chegada, aviao_num, qtd_disponivel)
VALUES (BZ-2010005, RIO DE JANEIRO, GOIANIA, 07:00:00,
13:00:00, A330, 399);

Listagem 5. Inserindo dados na tabela bilhete


INSERT INTO bilhete (bilhete_num, valor, desconto, valor_total,
viagem_classe, nome_passageiro, vo_num)
VALUES (B2-0000001, 100, 0, 100, 2, Joao Alverto Silva,
BZ-2010001);
.
. PARA DOWNLOAD DISPONVEL COM DADOS COMPLETOS, VEJA LINK NO
FINAL DO ARTIGO
.
INSERT INTO bilhete (bilhete_num, valor, desconto, valor_total,
viagem_classe, nome_passageiro, vo_num)
VALUES (B1-0000013, 585, 0, 585, 1, Ronaldo Mazzio, BZ-2010005);

Listagem 6. Inserindo dados na tabela departamento

Figura 3. Resultado do Select com Windowing function

Com isso atendemos ao primeiro pedido solicitado para o


sistema da Brazilian Airlines.

Requisio 2) Exibir na tela os vos que os Engenheiros


de vo criaram
Agora iremos atender ao segundo pedido feito para o sistema. Os Engenheiros de Vo da Brazilian Airlines criaram um
plano de vo para atender as cidades de Bauru, Goiania, Rio
de Janeiro e So Paulo. Desta forma, a companhia aria cobre
3 grandes cidades, alm de Bauru, interior do Estado de So
Paulo, devido a interligao rodoviria que esta cidade tem
com o centro-oeste paulista.
Os Engenheiros criaram tambm os horrios de sada e calcularam a hora aproximada de chegada. Rio de Janeiro e So Paulo
possuem mais possibilidades de vo do que Goinia e Bauru
devido baixa demanda. Entretanto, pode acontecer de um
determinado vo fazer um percurso maior para atingir uma
cidade prxima devido a alguns fatores como, por exemplo,

INSERT INTO departamento (id_departamento, departamento, ramal_


departamento)
VALUES (1, Marketing, 6110);
.
. PARA DOWNLOAD DISPONVEL COM DADOS COMPLETOS, VEJA LINK NO
FINAL DO ARTIGO
.
INSERT INTO departamento (id_departamento, departamento, ramal_
departamento)
VALUES (8, Faturamento, 6117);

Listagem 7. Inserindo dados na tabela funcionario


INSERT INTO funcionario (id_funcionario, funcionario, id_
departamento, cargo, salario, recebe_cesta_basica, recebe_plano_
saude, emprestimo_consignado, chefe_departamento)
VALUES (2, Marcos Nobrega, 1, Publicitrio, 1500, true,
true, false, false);
.
. DOWNLOAD DISPONVEL COM DADOS COMPLETOS, VEJA LINK NO FINAL DO
ARTIGO
.
INSERT INTO funcionario (id_funcionario, funcionario, id_
departamento, cargo, salario, recebe_cesta_basica, recebe_plano_
saude, emprestimo_consignado, chefe_departamento) VALUES (46,
Estevao Almeira, 8, Contador, 4500, true, true, false, true);

Listagem 8. Mdia de salrio por departamento usando Windowing Functions


1.

2.
3.
4.
5.
6.

SELECT id_funcionario, funcionario, cargo,


departamento,
salario, avg(salario)
OVER (PARTITION BY departamento)::numeric(9,2) AS media_departamento
FROM funcionario
INNER JOIN departamento ON
d
epartamento.id_departamento = funcionario.id_departamento
O
RDER BY media_departamento;

Edio 72 - SQL Magazine


SQL73.indb 17

17

25/02/2010 14:30:28

a necessidade de se ter o avio o mais cheio possvel. Este


procedimento chamado de Escala. So consideradas todas
as possibilidades para se chegar ao destino.
Listagem 9. Explicando o cdigo da Listagem 8
DA TABELA de funcionrios,
RETORNE APENAS OS DADOS DAS COLUNAS
O ID do funcionario,
O nome do funcionrio,
O cargo do funcionario,
O departamento ao qual ele est vinculado,
O seu salrio,
e A MDIA de salario SOBRE A TICA de todos os registros da
tabela departamento (ou seja, a mdia salarial por departamento)

Na Figura 4 esto apresentadas as rotas definidas pela


empresa, onde podemos perceber que clientes do Rio de
Janeiro podem voar at Bauru diretamente ou com Escala
em So Paulo, alm de voarem direto para Goinia ou
fazer escala em So Paulo para isso. O mesmo acontece
com So Paulo.

Listagem 10. Consulta aos vos criados.


WITH RECURSIVE consulta_recursiva (vo_num, cidade_partida,
cidade_chegada, conexao, hora_saida, hora_chegada) AS
(
SELECT f.vo_num, f.cidade_partida, f.cidade_chegada, 0,
hora_saida, hora_chegada::text FROM vos f
W
HERE f.cidade_partida = SAO PAULO OR f.cidade_partida =
RIO DE JANEIRO
UNION ALL
SELECT DISTINCT tabela.vo_num,recursivo.cidade_partida,
(recursivo.cidade_chegada || <= escala em; com
destino para => || tabela.cidade_chegada)::
varchar(100) AS cidade_chegada,

recursivo.conexao + 1,

recursivo.hora_saida,

(recursivo.hora_saida::time + tabela.hora_chegada::
interval)::text

FROM consulta_recursiva recursivo, vos tabela
W
HERE recursivo.cidade_chegada = tabela.cidade_partida

)
SELECT DISTINCT vo_num, cidade_partida, cidade_chegada,conexao, hora_
saida,hora_chegada FROM consulta_recursiva ORDER BY hora_chegada;

A diferena de alimentar uma CTE com um VALUE() e


um SELECT que este alimento dado ao CTE via SELECT
pode conter vrios registros, e automaticamente os parmetro sero testados com todos os registros deste SELECT.
Por isso, independente do segundo SELECT, j ser exibido
algum resultado em funo do primeiro SELECT. O segundo
SELECT s ir gerar dados quando ele atingir sua condio
WHERE: recursivo.cidade_chegada = tabela.cidade_partida, caso contrrio, o PostgreSQL ir exibir mais um registro
puro do primeiro SELECT. Podemos perceber isso mais
claramente observando o resultado da Figura 5.

Figura 5. Resultado da Consulta aos Vos

Figura 4. Rota area definida pela Brazilian Airlines

Os analistas do departamento de computao foram


felizes em adotar o novo PostgreSQL, porque contaram
com consultas recursivas (Nota DevMan 2), uma nova
possibilidade nesta verso novo do PostgreSQL. Com isso,
fica mais simples exibir os possveis vos disponveis pela
companhia area, conforme descrito na Listagem 10.
Como explicado na Nota DevMan 2, para haver recursividade necessrio um valor inicial. Na Listagem 10, a
consulta recursiva iniciada com o valor carregado de um
SELECT cuja condio admite apenas vos com partida de
So Paulo ou Rio de Janeiro, pois os engenheiros de vo da
Brazilian Airlines centralizaram a logstica de vo nestas
duas cidades para gerar o plano de vo.

18
SQL73.indb 18

Vamos dar uma observada de perto nos registros de nmero 6 e 7, vo_num BZ-2010002 e BZ-2010003 que possuem
ambos a coluna conexo = 1. Isso indica que estes dois vos
saram do Rio de Janeiro para So Paulo e de l seguiram
o destino final, Bauru e Goinia, respectivamente. Vejam
como foi fcil gerar este mapa, mas como funciona isso? A
resposta recursividade! Ns geramos as possibilidade de
vos com sada de So Paulo e Rio de Janeiro e o PostgreSQL
se encarregou de gerar o resultado.
Com isso, atendemos a mais um pedido requerido
para o sistema. Vamos agora atender ao ultimo pedido
solicitado.

Requisio 3) Na venda do Bilhete, vender somente a


quantidade liberada para um determinado vo
Os Engenheiros de vo da Brazilian Airlines definiram que
para um determinado vo deve-se vender apenas uma quantidade x de bilhetes. Esta quantidade limitada pela quantidade
de poltronas do avio ou pelo peso que ele carrega. Por isso,
ao se criar um vo, os Engenheiros atribuem a quantidade
mxima permitido de venda na coluna qtd_disponivel.

SQL Magazine - Conhea na Prtica os Novos Recursos do PostgreSQL 8.4


25/02/2010 14:30:29

postgresql

A cada bilhete vendido, o sistema invoca uma funo que o


pessoal da computao criou chamada func_substrai_qtd(voo_
num varchar(15), qtd int4) (descrita na Listagem 11) que ir
atualizar a tabela vos, cuja estrutura est sendo relembrada
na Figura 6.

Para a execuo, basta apenas informar o nmero do vo e a


quantidade de bilhetes que foram vendidos. No PostgreSQL
8.4, existe a possibilidade de se definir um valor padro para
os parmetros de uma function. Observe que isso foi feito para
a nossa funo logo na primeira linha da Listagem 10 atravs
do comando default, onde foi indicado que o valor 1 deveria
ser o valor padro.
Listagem 11. Funo que ir reduzir a disponibilidade de vendas.

Figura 6. Detalhes da tabela voos

A Listagem 11 apenas uma simples funo que realiza um


update diminuindo a disponibilidade de venda de bilhetes
para um determinado vo informado pelo primeiro parmetro,
voo_num (varchar(15)). O diferencial nesta funo a palavra
default no segundo parmetro. Podemos usar este comando
para automatizar alguns procedimentos na programao PL/
PGSQL, pois quando este parmetro for NULO, ento o PostgreSQL ir adotar o valor padro definido, por isso, podemos
fazer o que a Listagem 12 nos mostra.
A funo da Listagem 11 uma function escrita em PL/PGSQL. Podemos execut-la da forma descrita na Listagem 12.

CREATE OR REPLACE FUNCTION func_substrai_qtd(varchar(15),


integer default 1) RETURNS BOOLEAN AS
$$
DECLARE
existente int4;
qtd_alterada int4;
saida
boolean;
BEGIN
SELECT qtd_disponivel INTO existente FROM vos WHERE vo_num = $1;
IF (existente >= $2) THEN
q
td_alterada := existente - $2;
raise notice DISPONIVEL: %, qtd_alterada;
U
PDATE vos SET qtd_disponivel = qtd_alterada::int4
WHERE vo_num = $1;
ELSE
R
AISE NOTICE NAO SUBTRATIU, EXISTENTE e remover: %, %,
existente, $2;
END IF;
RETURN saida;
END;
$$
LANGUAGE plpgsql;

Listagem 12. Executando a funo func_subtrai_qtd.


SELECT func_substrai_qtd(BZ-2010001, 1);

Nota do DevMan 2
Consultas Recursivas Common Table Expression
As consultas recursivas eliminam boa parte da programao PL/PGSQL e lgica centralizada na camada Server ou Client. A soluo do item 2 ir depender da utilizao
deste nova implementao, e para esclarecer o funcionamento primeiro vamos entender como montar uma consulta recursiva, no mesmo molde dos primeiros passos
de recursividade quando estamos aprendendo a programar, fazendo um exemplo de
somatria recursiva:
WITH RECURSIVE soma_recursiva(parametro)
AS
( VALUES (1) UNION ALL SELECT parametro +1 FROM coisa WHERE parametro < 2 )

SELECT sum(parametro) FROM soma_recursiva:


Ao analisarmos apenas a ltima linha, na verdade no estamos realizando um SELECT
da tabela soma_recursiva e sim de uma expresso, como se fosse uma funo criada em
PL/PGSQL. Portanto, a lgica da recursividade fica dentro desta expresso chamada de
COMMON TABLE EXPRESSION ou simplesmente CTE.
O que unifica os parmetros enviados para uma CTE com as tabelas que iremos trabalhar dentro de uma CTE justamente a sintaxe UNION ALL que ir entregar o parmetro
enviado pela ltima linha (SELECT sum(paramentro) FROM soma_recursiva) para o SELECT aps ele; lembrando que este select finaliza com a invocao da prpria CTE para
se tornar recursiva.

SELECT sum(parametro) FROM soma_recursiva;

O resultado da consulta acima seria 3! Mas como funciona isso?


Na consulta exemplo acima, atravs do WITH RECURSIVE criamos uma COMMON TABLE EXPRESSION, ou seja, a regra de negcios para que a consulta recursiva funcione.
O comando WITH finalizado com a sentena:

Antes do UNION ALL temos o VALUE (): Esta funo realiza o mesmo servio quando
usado dentro do INSERT, ou seja, define valores para os campos. Sendo assim, atravs
do VALUE() iremos definir os valores iniciais dos parmetros criados na CTE, porm podemos definir estes valores iniciais atravs de um SELECT, ou seja, s se usa o VALUE()
quando sabemos de fato os valores de incio para que nossa consulta recursiva funcione.
Como no exemplo acima, o valor inicial da CTE soma_recursiva tem VALUE 1 para a
varivel parmetro, e usamos a funo SUM() para increment-lo.

SELECT parmetro1, parametro2, ..., da common table expression FROM nome da


common table expression. justamente neste momento que a recursividade comea.
Vamos analisar a consulta acima de traz para frente:

Edio 72 - SQL Magazine


SQL73.indb 19

19

25/02/2010 14:30:29

SELECT func_substrai_qtd(BZ-2010001);

Comparativo entre a Verso 8.3 e 8.4 do PostgreSQL


Uma questo importante para quem est na verso 8.3.8
saber o quanto est perdendo em permanecer nesta verso. O
que demonstramos em nosso projeto fictcio so recursos interessantes que auxiliam o desenvolvedor de forma produtiva,
mas e no desempenho?
O Dr. Jignesh K. Shah, Engenheiro da SUN, realizou uma
palestra muito interessante na PGCON 2009 que foi realizada na Universidade de Ottawa em Maio, onde realizou
um comparativo de desempenho entre as duas verses.
Os dados completos esto em seu blog, citado ao final na
Seo links - Performance Comparison of PostgreSQL 8.4 VS
PostgreSQL 8.3.
Fazendo um resumo de seus comparativos, pode-se concluir
que: O PostgreSQL 8.4 est cerca de 5% mais rpido. Isso
significa que em muitos pontos a nova verso ganhou em velocidade, mas em outras perdeu. Para no assustar os leitores,
este resultado previsvel, pois a nova verso ganhou novas
funcionalidades (mais de 293) que geram custo para trazer um
resultado, por exemplo, a nova ACL por coluna. Agora esta
verso tem um novo nvel de check para realizar.
assim mesmo, novas funcionalidades podem gerar um custo maior, entretanto, os testes do Dr. Shah provam um acrscimo geral entre o ltimo release da srie 8.3 e o novo 8.4

Existem estudos que demonstram superioridade de desempenho entre o PostgreSQL e bancos comerciais como o DB2,
SQL Server e Oracle. Em uma migrao que realizamos de

20
SQL73.indb 20

Download do projeto deste artigo


www.datapower.com.br/sql/2010/projeto_01.zip
NOTA Novidades do PostgreSQL 8.4
www.postgresql.org/about/press/presskit84.html.br
ENTENDA Recursividade no DB2
http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/topic/rzajq/rzajqrecursive.htm
ENTENDA Recursividade no SQL Server
http://msdn.microsoft.com/en-us/library/ms186243.aspx
Performance Comparison of PostgreSQL 8.4 VS PostgreSQL 8.3
http://blogs.sun.com/jkshah/resource/pgcon2009_8384p.pdf

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:

Feedback
eu
sobre e
s

Concluso

Links

D
s

Listagem 13. Executando a funo func_subtrai_qtd em informar parmetro.

dados do Oracle para o PostgreSQL, uma arquivo EDI de importao demorava 30 minutos para ser importado no Oracle,
j no PostgreSQL apenas 20 segundos. Entretanto, o Oracle
possua tantos recursos que para um projeto mais complexo
o PostgreSQL no atenderia. Desta forma, nesta nova verso o
PostgreSQL, alm de 5% mais rpido que a verso 8.3.8, ganhou
muitos recursos que permite ir mais longe. Existe a promessa
para que na verso 8.5 o PostgreSQL venha com ferramentas
nativas para Clusterizao como por exemplo REPLICAO
SINCRONA. Isso possibilita uma concorrncia muito grande
com o Oracle RAC, lembrando ainda da questo financeira j
que o PostgreSQL FREE.
Para apoiar na anlise mais prtica desta nova verso do
PostgreSQL, realizamos a modelagem e projeto de um banco
de dados de uma companhia area fictcia. Neste contexto, consideramos algumas situaes comuns de serem encontradas
no dia-a-dia de um DBA onde os novos recursos podem ser
empregados, e onde apresentam resultados muito interessantes, tornando as tarefas bastante simples.

edio
ta

O que vemos na Listagem 13 a mesma funo anterior,


enviando por parmetro apenas o varchar(15) que seria o vo
de nmero BZ-2010001. Isso far com que o valor assumido
pela funo para o parmetro quantidade de bilhetes vendidos
seja igual a 1. Isso acontece, como dito anteriormente, porque
definimos que o integer (int4) receberia por padro o valor 1
se acaso no fosse especificado um valor.

www.devmedia.com.br/sqlmagazine/feedback

SQL Magazine - Conhea na Prtica os Novos Recursos do PostgreSQL 8.4


25/02/2010 14:30:33

postgresql

Edio 72 - SQL Magazine


SQL73.indb 21

21

25/02/2010 14:30:39

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

A Linguagem PL/Java do PostgreSQL


Parte 2 Instalao e Preparao do Ambiente
De que se trata o artigo?
Descrio e demonstrao da preparao do ambiente do banco de dados para receber a mquina
virtual Java, utilizando-a para a instalao da linguagem procedural PL/Java e desenvolvimento de
funes que usam classes Java.

Para que serve?


Clailson de Almeida
clailson.dba@gmail.com

Graduado em Tecnologia em Processamento


de Dados e ps-graduado em Administrao de Banco de Dados pela Universidade
Tiradentes (UNIT), no estado de Sergipe. J
atuou como desenvolvedor WEB, com forte
utilizao de Java. J trabalhou 2 anos como
Analista de Sistemas e possui experincia
no desenvolvimento com bancos de dados
Oracle, SQL Server e PostgreSQL, sendo que,
deste ltimo, tem 6 anos de utilizao, dos
quais 4 anos e meio como DBA. Atualmente
trabalha em uma softhouse privada, na cidade de Aracaju, Sergipe, como gerente da
rea de banco de dados. Possui certificao
PostgreSQL, pela Pearson Vue, com o ttulo
de PostgreSQL CE (PostgreSQL Certified
Engineer Open Source Software) 8 Silver.
Realiza consultoria especializada em banco
de dados e ministra cursos e treinamentos
em PostgreSQL. Est estudando atualmente
para a certificao OCA Oracle.

22
SQL73.indb 22

esta srie de artigos estamos


demonstrando a utilizao da
linguagem PL/Java no PostgreSQL, ampliando ainda mais as
possibilidades de desenvolvimento de
funes e triggers, atravs da linguagem
Java.
Na primeira parte deste artigo, descrevemos algumas caractersticas da
linguagem procedural PL/Java, e mostramos como os mdulos, classes e toda
estrutura do Java trabalha junto com
o backend do SGBD, para que as funes e triggers utilizem as classes Java
desenvolvidas.
Nesta segunda parte, descreveremos
como preparar um servidor de banco
de dados PostgreSQL para utilizar o PL/
Java no desenvolvimento de funes.

Descrever a configurao do servidor de banco de


dados para utilizar a linguagem Java. Serve tambm
para mostrar como o PostgreSQL pode ser configurado para reconhecer os objetos compartilhados do
Java e do mdulo PL/Java, bem como a instalao da
linguagem PL/Java.

Em que situao o tema til?


Possibilidade de migrao das regras de negcio, escritas em Java, da camada de aplicao
para o banco de dados, aumentando os recursos do mesmo com a utilizao e manipulao
direta dos dados pelo Java.

Preparao esta que vai desde a instalao da JVM (a mquina virtual Java),
passando pela configurao do PostgreSQL, at a instalao propriamente dita
da linguagem.

SQL Magazine - A Linguagem PL/Java do PostgreSQL


25/02/2010 14:30:40

postgresql

A verso do PL/Java aqui discutida a 1.4.0, com o PostgreSQL na verso 8.3.7, em ambiente Linux (CentOS 5.2).

Pr-requisitos para Execuo do PL/Java

Depois da alterao do arquivo, devemos recarregar as


configuraes com o utilitrio ldconfig, bastando digit-lo
na linha de comando.

Antes de iniciarmos o download e instalao do PL/Java,


precisamos ter instalado no servidor de banco de dados:
PostgreSQL com verso a partir da 8.0.3 (detalhes e comentrios para cada verso acima ou abaixo desta, podem ser vistos
na primeira parte deste artigo);
O driver JDBC do PostgreSQL (necessrio apenas se for utilizado o programa Deployer comentado mais a frente para
instalao do PL/Java);
Runtime do Java (JRE) com verso a partir da 1.4 ou GCJ a
partir da 4.0.x (apenas para Linux).

[root@localhost ~]# ldconfig

Configurao do Ambiente do Servidor

set PATH=%PATH%;%JAVA_HOME%\bin;%JAVA_HOME%\bin\client

Como um dos pr-requisitos para o funcionamento do PL/


Java, precisamos instalar o runtime do Java no servidor de
banco de dados. Para isso, devemos acessar o site da Sun
(ver seo Links) e fazer o download da verso mais recente.
Neste artigo foi usado o arquivo jre-6u15-linux-i586-rpm.
bin (Java 6, update 15). Feito o download, devemos tornar
o arquivo binrio executvel e instalar o mesmo, com os
comandos abaixo:

Assim como no Linux, para esta configurao ficar permanente necessrio editar a varivel PATH na seo Variveis de
Ambiente, que est na guia Avanado das Propriedades do Sistema (boto direito do mouse em Meu Computador>Propriedades
do Sistema>Avanado>Variveis de Ambiente) (Figura 1).

Listagem 1. Contedo do arquivo ld.so.conf


...
$JAVA_HOME/lib/i386/server
$JAVA_HOME/lib/i386/client
$JAVA_HOME/lib/i386/ native_threads
...

No sistema operacional Windows, basta configurar a varivel de ambiente PATH, como mostrado abaixo, na linha de
comando do prompt do DOS.

chmod a+x jre-6u15-linux-i586-rpm.bin


./jre-6u15-linux-i586-rpm.bin

Com o trmino da instalao e a execuo do comando java


-version, ser obtido o resultado mostrado abaixo. Caso o resultado no seja este, devemos verificar as ocorrncias de erros e
proceder novamente com a instalao do Java.
[root@localhost ~]# java -version
java version 1.6.0_15
Java(TM) SE Runtime Environment (build 1.6.0_15-b03)
Java HotSpot(TM) Client VM (build 14.1-b02, mixed mode, sharing)

Com o Java instalado, necessrio dizer ao servio do


PostgreSQL (postmaster), bem como s outras aplicaes que
utilizam o Java, onde encontrar os objetos compartilhados
utilizados pelo Java Runtime Environment (JRE).
Falando especificamente do PostgreSQL, esta configurao
do Java s se aplica ao postmaster, ou seja, ao processo servidor
(backend). Para os clientes, como o psql, isto no necessrio.
Em ambientes Linux/Unix, a varivel de ambiente LD_LIBRARY_PATH deve ser configurada como apresentado a
seguir. Esta configurao aponta para os diretrios onde esto
os objetos compartilhados do Java.
export LD_LIBRARY_PATH=$JAVA_HOME/lib/i386/server:$JAVA_HOME/lib/
i386/client:$JAVA_HOME/lib/i386/native_threads

Alternativamente, podemos editar o arquivo /etc/ld.so.conf


para incluir os caminhos dos diretrios dos objetos compartilhados do Java (Listagem 1). Esta edio pode ser feita em
qualquer editor de texto do Linux, e o objetivo desta modificao deixar permanente a configurao do path das bibliotecas
Java, mesmo depois do boot do servidor.

Figura 1. Configurao permanente do PATH no Windows

No ambiente Linux/Unix, alm da configurao do caminho


de procura para os objetos compartilhados do Java, pode ser
necessrio resolver um conflito entre a verso da biblioteca
libzip.so, includa no JRE, e a verso da biblioteca libz.so, do
sistema operacional, usada pelo PostgreSQL.
Convm notar que a libzip.so j contem a libz.so. Estas bibliotecas so escritas em C e servem para leitura, criao e modificao de arquivos compactados. importante dizer tambm
que este problema s acontece em algumas plataformas, por
exemplo, servidores com o sistema operacional Debian.
O sintoma do problema um InternalError na classe java.
util.zip.Inflater, quando feito a tentativa de carregar a
classe de compresso utilizando o mtodo init(). Este mtodo pode utilizar um parmetro chamado nowrap, que diz
classe java.util.zip.Inflater se para utilizar o suporte de
compresso compatvel com o mtodo GZIP ou no. Se true, a
classe utiliza mtodos de otimizao nativas da ZLIB. neste
ponto que o erro pode acontecer, pois estes mtodos podem

Edio 72 - SQL Magazine


SQL73.indb 23

23

25/02/2010 14:30:40

ter implementaes diferentes, caso a verso da libzip.so seja


diferente da libz.so.
Para verificar as verses de libzip.so e de libz.so, podemos utilizar o utilitrio strings na linha de comando (Listagem 2).
Listagem 2. Verses das bibliotecas libzip.so e libz.so
[root@localhost ~]# strings $JAVA_HOME/lib/i386/libzip.so |
fgrep Copyright
deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly
inflate 1.1.3 Copyright 1995-1998 Mark Adler
[root@localhost ~]# strings /usr/lib/libz.so.1.2.3 | fgrep
Copyright
deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly
inflate 1.2.3 Copyright 1995-2005 Mark Adler

Neste caso, h diferena de verses, mas em nosso ambiente de teste, executando o CentOS 5.2, no houve conflito. Mas
se ocorresse, o problema poderia ser resolvido de quatro
maneiras diferentes, dependendo apenas das necessidades do administrador e habilidades na recompilao do
PostgreSQL:
Se possvel, utilizar uma nova verso do JRE que tenha
a mesma verso da libz.so. Esta a soluo mais adequada.
Infelizmente, para saber se a verso compatvel necessrio instalar o JRE e executar o utilitrio strings, ou verificar
alguma nota de liberao da verso do Java (release notes);
Modificar a varivel de ambiente do Linux, chamada de
LD_PRELOAD (ler Nota DevMan 1), para apontar para
a biblioteca libzip.so, do JRE. Isto forar o uso da verso
da biblioteca que est no JRE. Essa soluo far com que o
postmaster use a libzip.so no lugar da libz.so;
Reconfigurar o cdigo fonte do PostgreSQL com a opo
--without-zlib, recompilar e reinstalar o mesmo. Isto ir desabilitar todo o suporte de compresso do servio postmaster.
Para ter de volta o suporte, preciso recompilar novamente
o PostgreSQL, voltando tambm o conflito entre as verses
das bibliotecas de compresso;
Obter uma verso da libz.so que corresponda verso da
libzip.so, utilizada pelo JRE, e fazer uma reconfigurao na
execuo do servio do PostgreSQL para apontar para esta
nova verso da libz.so.

Nota do DevMan 1
LD_PRELOAD
uma varivel de ambiente que aponta para bibliotecas compartilhadas criadas
pelo usurio. Estas bibliotecas podem conter nomes de funes com os mesmos
nomes das funes do sistema operacional que se deseja sobrescrever, ou at mesmo, novas funcionalidades. utilizada quando desejamos colocar uma biblioteca
criada entre a chamada de um programa e a sua prpria biblioteca, sem ter que
sobrescrever a biblioteca original. Por exemplo, pode-se usar a LD_PRELOAD para
sobrescrever uma funo da biblioteca dos mdulos de um leitor de carto smartcard para mostrar uma mensagem de erro traduzida, validaes de dados ou at
mesmo informaes teis para o usurio.

24
SQL73.indb 24

Download do PL/Java
Com os pr-requisitos verificados e o Java instalado no servidor
de banco de dados, podemos prosseguir com o download do PL/
Java. Os arquivos necessrios para a instalao da linguagem
procedural podem ser encontrados no pgFoundry, o site oficial
do grupo de desenvolvimento do projeto PL/Java, e de outros
projetos externos (add-ons) para o PostgreSQL (ver seo Links).
Acessando o site devemos clicar na seo Arquivos, onde
iremos encontrar os pacotes binrios de instalao da verso
1.4.0 do PL/Java (o arquivo pljava-i686-pc-linux-gnu-pg8.31.4.0.tar.gz). Esto disponveis instaladores para as verses
mais recentes do PostgreSQL (8.1, 8.2 e 8.3), para Linux 32 e 64
bits, e para Windows 32 bits. Todos os pacotes binrios para
download foram montados para utilizarem a configurao
padro de uma JVM.
Tambm disponibilizado o cdigo fonte do PL/Java para
compilao em outras plataformas.
O PL/Java pode ser compilado com o GNU GCJ (conforme
explicado na primeira parte deste artigo). Entretanto, no
existem pacotes binrios pr-compilados para GCJ, mas o
utilitrio make, no ambiente Linux, contm o necessrio para
a construo e compilao destes pacotes binrios.

Instalao do Pacote Binrio do PL/Java


Para a instalao do pacote binrio basta descompact-lo
em qualquer diretrio no sistema de arquivo, uma vez que o
servidor do PostgreSQL ser configurado para o reconhecimento deste mdulo.
Vamos ento criar um diretrio chamado pljava, dentro do
diretrio /var/lib/pgsql e descompactar o arquivo pljava-i686pc-linux-gnu-pg8.3-1.4.0.tar.gz (conforme os comandos da
Listagem 3).
Listagem 3. Criao e descompactao do pacote binrio do PL/Java.
[root@localhost ~]# mkdir /var/lib/pgsql/pljava
[root@localhost ~]# cp pljava-i686-pc-linux-gnu-pg8.3-1.4.0.
tar. gz /var/lib/pgsql/pljava
[root@localhost ~]# cd /var/lib/pgsql/pljava
[root@localhost ~]# tar xvf pljava-i686-pc-linux-gnu-pg8.31.4.0.tar.gz

Com o pacote descompactado, vamos mudar as permisses


de acesso do diretrio pljava e dos seus arquivos. Assim,
apenas o usurio postgres poder acess-los. Isso feito
porque ele o super usurio master, dono do servio postmaster e de toda estrutura de diretrios do agrupamento
de banco de dados. Portanto, aumentaremos a segurana
deixando o diretrio pljava com as mesmas permisses de
acesso das outras pastas e arquivos que esto dentro do
caminho /var/lib/pgsql.
Na Listagem 4, com o comando chown, trocamos recursivamente o dono dos arquivos e diretrio no caminho /var/lib/
pgsql/pljava. Depois, com o comando chmod, trocamos as permisses de leitura, escrita e execuo, ou seja, nenhum outro
usurio ou grupo pode ter acesso a estes arquivos, apenas o
usurio postgres.

SQL Magazine - A Linguagem PL/Java do PostgreSQL


25/02/2010 14:30:40

postgresql

Listagem 4. Mudana das permisses de acesso dos arquivos


do PL/Java.
chown postgres:postgres -R /var/lib/pgsql/pljava
chmod 700 -R /var/lib/pgsql/pljava

Configurao do PostgreSQL
Para que o mdulo PL/Java seja reconhecido e
funcione corretamente, necessrio configurar o
servidor PostgreSQL, modificando o arquivo postgresql.conf do diretrio /var/lib/pgsql/data.
Existem duas formas de fazer com que o PostgreSQL encontre os objetos e classes do PL/Java. A
primeira descompactar o pacote binrio dentro de
um diretrio de procura do servio postmaster (nome
do servio do PostgreSQL), como o diretrio data. A
outra forma dizer ao postmaster onde encontrar tais
objetos, atravs da varivel dynamic_library_path,
no arquivo postgresql.conf. A configurao default
desta varivel mostrada abaixo:
#dynamic_library_path = $libdir

Devemos retirar o comentrio da linha (apagando


a #) e adicionar o caminho onde se encontram os
arquivos que foram extrados do pacote binrio do
PL/Java, de acordo com o cdigo abaixo.

descries so exibidos na Tabela 1. A Listagem 5 mostra um exemplo


de configurao dessas variveis.
Normalmente o cdigo Java carregado nas bases de dados atravs
das funes SQL do PL/Java (install_jar/replace_jar/remove_jar) que
sero detalhadas na parte trs desta srie. Mas estas funes, bem
como a maior parte do cdigo que compe o mdulo PL/Java, so
escritas em Java. Portanto, necessrio dizer ao PostgreSQL onde
encontrar os objetos que fazem parte da linguagem procedural. Esta
configurao realizada atravs do parmetro classpath do PL/Java,
como descrito abaixo.
pljava.classpath = <diretrio de instalao do pljava>/pljava.jar

Listagem 5. Configurao dos parmetros do PL/Java.


pljava.classpath = /var/lib/pgsql/pljava/pljava.jar
pljava.statement_cache_size = 10
pljava.release_lingering_savepoints = true
pljava.vmoptions = -Xmx64M
pljava.debug = false

Com as modificaes realizadas no arquivo postgresql.conf, basta reiniciar


o servidor do PostgreSQL para que o novo mdulo seja reconhecido e a
linguagem procedural PL/Java possa ser instalada nas bases de dados.

dynamic_library_path = $libdir:<diretrio de instalao


do pljava>

No Windows, deve-se usar o ponto e vrgula (;)


como separador de bibliotecas, e barras duplas (//)
como separador de diretrios. Vamos modificar esta
varivel deixando-a no formato:
dynamic_library_path = $libdir:/var/lib/pgsql/pljava

Podemos alterar tambm o valor da varivel


log_min_messages para podermos visualizar mais
informaes sobre a execuo das classes no log do
PostgreSQL, como sada de informaes de buffers
ou mensagens de erro que so repassadas para
eventos de try-catch, assim como outras informaes
relevantes para debug das classes.
log_min_messages = info

O PL/Java faz uso da varivel custom_variable_classes, na seo CUSTOMIZED OPTIONS,


para poder configurar o mdulo do PL/Java. Dessa
forma, precisamos alterar esta varivel e incluir
uma varivel de classe chamada pljava, conforme
o cdigo:
custom_variable_classes = pljava

Com isso, podemos configurar os parmetros


utilizados pelo PL/Java. Estes parmetros e suas

Edio 72 - SQL Magazine


SQL73.indb 25

25

25/02/2010 14:30:41

Parmetro

Descrio

classpath

Define o classpath que a JVM usa quando carrega a biblioteca inicial do PL/Java. Utilizado apenas quando no se usa o GCJ.

statement_cache_size

Define o tamanho do cache para Prepared Statements (ler Nota DevMan 2).

release_lingering_savepoints

Se true, savepoints em espera sero liberados na sada da funo, ou seja, se foi criado um savepoint em espera, dentro da funo, o mesmo poder ficar aguardando
o retorno do commit dos bancos de dados distribudos, mesmo depois da funo finalizar sua execuo. Se false, os savepoints sero desfeitos (rollback). Isto til
para transaes com servidores distribudos.
Define as opes de inicializao para a JVM, por exemplo:
pljava.vmoptions = -Xms64M Xmx128M -Xbatch

vmoptions

debug

Neste caso, estamos configurando a JVM para utilizar inicialmente 64 MB de memria, podendo atingir at 128 MB (opes Xms e Xmx, respectivamente). Estamos
dizendo tambm para a JVM desabilitar qualquer compilao em background (opo Xbatch).
Este parmetro segue o mesmo formato das opes de inicializao de uma JVM comum.
Se true, far com que o processo postgres fique em standby na primeira chamada linguagem Java, com o intuito de verificar, linha por linha, o cdigo interno do
PL/Java, na linguagem C. Portanto, esta varivel s til para debug do PL/Java se for necessrio verificar um bug no mdulo PL/Java ou no desenvolvimento de
novas funcionalidades.
Segue o mesmo princpio de debug de uma classe Java em uma IDE, como o Netbeans.

Tabela 1. Parmetros do PL/Java

Nota do DevMan 2
Prepared Statements
um objeto da API Java que permite o desenvolvimento de templates de queries
SQL que podem ser reutilizadas para efetuar comandos iguais com diferentes valores
de parmetros. Essencialmente o que feito criar a query, que pode ser de qualquer
tipo (INSERT, UPDATE, etc.), deixando os valores das variveis indefinidos. Ento, podemos especificar valores para os elementos indefinidos antes de executar a query, alm
de podermos executar o mesmo comando vrias vezes, bastando trocar os valores das
variveis de entrada. Um exemplo de query que montada em um prepared statement SELECT * FROM CLIENTES WHERE CODIGO > ? AND CATEGORIA = ?.

Instalao do PL/Java nas Bases de Dados


A instalao da linguagem procedural PL/Java pode ser feita
de duas maneiras. A mais simples executando o arquivo
install.sql dentro da base de dados. Este arquivo est dentro do
diretrio onde foi descompactado o pacote binrio. No nosso
caso, o arquivo se encontra no diretrio /var/lib/pgsql/pljava.
Existe tambm o arquivo uninstall.sql para remover a linguagem PL/Java do database. A estrutura criada ser explicada
na prxima seo.
Tanto para a execuo do arquivo install.sql como para o
uninstall.sql, necessrio que o usurio que esteja executando
tenha privilgios de super usurio.
Para demonstrar esta primeira forma de instalao da linguagem procedural PL/Java, iremos criar uma base de dados
chamada sql_magazine_pljava e executar o arquivo install.
sql (Listagem 6).

Com a instalao concluda, basta acessar a base de dados e


verificar as tabelas e funes criadas no esquema sqlj, que foi
criado para guardar toda a estrutura do PL/Java, separando-a
da estrutura e esquemas do usurio.
Depois disso, iremos executar o arquivo uninstall.sql para
desinstalar o PL/Java e podermos instal-lo novamente, utilizando a segunda forma de instalao.
psql -U postgres sql_magazine_pljava -1 -f /var/lib/pgsql/pljava/
uninstall.sql

A segunda forma de instalar a linguagem PL/Java utilizando um programa de deploy que nos permite instalar, reinstalar
e remover a linguagem da base de dados. Este programa j
disponibilizado pelo PL/Java e precisa que o usurio que o
est executando tenha privilgios de super usurio. Tambm
necessria a utilizao do driver JDBC do PostgreSQL no seu
classpath. Para verificar as opes do programa deploy, basta
executar o comando abaixo.
java -cp /var/lib/pgsql/pljava/deploy.jar:/var/lib/pgsql/pljava/
postgresql-8.3-605.jdbc4.jar org.postgresql.pljava.deploy.Deployer

Observe que na opo -cp (classpath), do comando java, foi


informado o caminho do pacote JAR do deploy, que est em /
var/lib/pgsql/pljava. Foi informado tambm onde o programa
encontrar o driver JDBC do PostgreSQL. Neste caso, estamos
utilizando o driver para a verso 6 do Java e o mesmo foi colocado no diretrio onde o pacote do PL/Java foi descompactado.
Com a execuo do comando acima, ser mostrada a lista de
opes disponveis do programa deploy (Listagem 7).
Listagem 7. Opes do programa de deploy do PL/Java.

Listagem 6. Criao da base sql_magazine_pljava e instalo da linguagem


PL/Java.
createdb -U postgres sql_magazine_pljava -E LATIN1 -T template0
psql -U postgres sql_magazine_pljava -1 -f /var/lib/pgsql/
pljava/install.sql

26
SQL73.indb 26

usage: java org.postgresql.pljava.deploy.Deployer


{-install | -uninstall | -reinstall}
[ -host <hostName>
]
# default is localhost
[ -port <portNumber>
]
# default is blank
[ -database <database> ]
# default is name of current user
[ -user <userName>
]
# default is name of current user
[ -password <password> ]
# default is no password

SQL Magazine - A Linguagem PL/Java do PostgreSQL


25/02/2010 14:30:41

postgresql

A sintaxe do comando pode ser vista abaixo, e na Tabela 2


podemos ver cada opo e sua descrio.
java -cp <classpath para os arquivos .jar do deploy e do driver
JDBC do PostgreSQL> org.postgresql.pljava.deploy.Deployer [ opes ]

Utilizando a mesma base de dados sql_magazine_pljava, onde


j instalamos o PL/Java pelo mtodo mais simples (utilizando
o arquivo install.sql), vamos instalar novamente a linguagem
utilizando o programa de deploy, como mostrado a seguir:

java -cp /var/lib/pgsql/pljava/deploy.jar:/var/lib/pgsql/pljava/


postgresql-8.3-605.jdbc4.jar org.postgresql.pljava.deploy.Deployer
-install -user postgres -database sql_magazine_pljava

Estrutura do Esquema SQLJ


Como foi comentado na seo anterior, depois da instalao do PL/Java, seja pela execuo do arquivo install.sql
ou pelo programa de deploy do PL/Java, so criadas vrias
tabelas e funes dentro de um novo esquema na base de
dados, chamado de sqlj. A Tabela 3 mostra a descrio de
cada objeto e funciona como um dicionrio de dados da

Opo

Descrio
Instala a linguagem procedural PL/Java na base de dados juntamente com as funes e tabelas que o PL/Java utiliza. A instalao
falhar se a linguagem j estiver criada.
Reinstala a linguagem procedural PL/Java na base de dados juntamente com as funes e tabelas que o PL/Java utiliza. Este comando
executar efetivamente um drop em todos os pacotes JAR que foram carregados na base de dados. Por isso ser necessrio carregar
novamente todos os JAR instalados.
Remove a linguagem procedural PL/Java da base de dados juntamente com as funes e tabelas que o PL/Java utiliza e todos os
JAR carregados.

-install

-reinstall

-uninstall
-user <user name>

Nome do usurio que ir se conectar a base de dados. O default o usurio do sistema operacional corrente.

-password <password>

Senha do usurio que ir se conectar a base de dados. O default sem senha.

-database <database>

O nome do banco de dados destino onde a linguagem PL/Java ser manipulada. O default a base com o mesmo nome do usurio
da conexo. Ou seja, se o comando for executado com o usurio carlos e sem especificao do banco, o PostgreSQL ir procurar uma
base de dados com o nome carlos.

-host <host name>

Nome do host da conexo. O default localhost.

-port <port number>

Nmero da porta da conexo. O default vazio.

Tabela 2. Descrio das opes do programa de deploy do PL/Java


Estrutura

Descrio

SCHEMA sqlj

Esquema onde esto instalados os objetos para utilizao da linguagem PL/Java.

LANGUAGE java

Linguagem marcada como TRUSTED.

LANGUAGE javaU

Linguagem marcada como NOT TRUSTED.

SEQUENCE sqlj.jar_entry_entryid_seq

Objeto sequence (ler Nota DevMan 3) utilizado pela tabela sqlj.jar_entry.

SEQUENCE sqlj.jar_repository_jarid_seq

Objeto sequence utilizado pela tabela sqlj.jar_repository.

SEQUENCE sqlj.typemap_entry_mapid_seq

Objeto sequence utilizado pela tabela sqlj.typemap_entry.

TABLE sqlj.jar_repository

Tabela que armazena as informaes dos pacotes JAR das classes desenvolvidas pelo usurio.

TABLE sqlj.jar_entry
TABLE sqlj.classpath_entry
TABLE sqlj.typemap_entry

Tabela que armazena as informaes das classes que compem cada pacote JAR instalado. Possui uma
linha para cada classe, bem como uma coluna que guarda seu cdigo compilado (.class).
Tabela que armazena as informaes de configurao do classpath dos pacotes JAR dentro do servidor
de banco de dados.
Tabela que armazena as informaes de tipos complexos criados para utilizao com as funes em
PL/Java.

FUNCTION sqlj.java_call_handler

Interpretador/manipulador da linguagem java.

FUNCTION sqlj.javau_call_handler

Interpretador/manipulador da linguagem javaU.

FUNCTION sqlj.install_jar

Funo que instala os pacotes JAR criados pelo usurio.

FUNCTION sqlj.replace_jar

Funo que atualiza os pacotes JAR criados pelo usurio.

FUNCTION sqlj.remove_jar

Funo que remove os pacotes JAR criados pelo usurio.

FUNCTION sqlj.set_classpath

Funo que define um classpath para o pacote JAR instalado.

FUNCTION sqlj.get_classpath

Funo para recuperar o classpath do pacote JAR instalado.

FUNCTION sqlj.add_type_mapping

Funo para adicionar um tipo complexo na linguagem PL/Java.

FUNCTION sqlj.drop_type_mapping

Funo para remover um tipo complexo na linguagem PL/Java.

Tabela 3. Estrutura criada pela instalao do PL/Java

Edio 72 - SQL Magazine


SQL73.indb 27

27

25/02/2010 14:30:41

estrutura criada. Os detalhes de utilizao sero descritos


na terceira parte desta srie.

Concluso

D seu voto sobre este artigo, atravs do link:


www.devmedia.com.br/sqlmagazine/feedback

sobre e
s

A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos
saber o que voc, leitor, acha da revista!

Objeto Sequence
Este objeto utilizado dentro do banco de dados para fazer uma espcie de
autoincremento, utilizando nmeros sequenciais positivos ou negativos para
uma coluna especfica, geralmente uma coluna de chave primria, ou quando uma
aplicao necessita utilizar valores numricos sequenciais em uma tabela. Esses
valores so gerados automaticamente pelo banco de dados.

Links
Site Oficial do PostgreSQL
http://www.postgresql.org/

Feedback
eu

edio
ta

D seu feedback sobre esta edio!

D
s

Ao longo deste artigo podemos demonstrar como relativamente simples a configurao do servidor de banco de
dados PostgreSQL e a instalao da linguagem procedural
PL/Java.
Mais detalhes sobre as funes disponibilizadas pelo mdulo PL/Java sero apresentados no prximo artigo, onde
exemplificaremos algumas funes, bem como demonstraremos como so escritas as classes Java para utilizao com
o PL/Java. At a prxima.

Nota do DevMan 3

Site do projeto PL/Java no PgFoundry


http://pgfoundry.org/projects/pljava/
Download do PL/Java
http://pgfoundry.org/frs/?group_id=1000038
Site Oficial do Java
http://java.sun.com/
Doc API Java Standard Edition 6
http://java.sun.com/javase/6/docs/api/
Download do Java 6
http://www.java.com/pt_BR/download/manual.jsp

28
SQL73.indb 28

SQL Magazine - A Linguagem PL/Java do PostgreSQL


25/02/2010 14:30:42

Seo Projeto/Modelagem

sql server
Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Administrando o SQL Server com uma


Ferramenta Web
Conhea o SQL Server Web Data Administrator
De que se trata o artigo?

I
Nilton Pinheiro
niltonpinheiro@msn.com

formado em Anlise de Sistemas e psgraduado em Redes Corporativas. Possui


8 anos de experincia com SQL Server,
dos quais a 7 trabalha como DBA em uma
conceituada instituio financeira em So
Paulo. Como um Beta Tester Microsoft trabalha com o SQL Server 2008 desde seu Beta
1. Possui as certificaes MCDBA, MCTS:
SQL Server 2005, MCITP: SQL Server 2005
e MCSE, MVP (Microsoft Most Valuable
Professionals) em SQL Server e fundador do
portal www.mcdbabrasil.com.br.

niciaremos este artigo fazendo uma


pergunta: alguma vez voc teve
a necessidade de administrar um
servidor ou instncia do SQL Server
utilizando uma ferramenta que pudesse
funcionar a partir de um browser? E se
eu lhe disser que esta ferramenta existe?
E o melhor, que ela totalmente grtis?
Pois bem, verdade que pouca gente
sabe, mas ainda na poca do SQL Server
2000 a Microsoft disponibilizou um ferramenta chamada SQL Server Web Data
Administrator que tinha, ou melhor, tem
como objetivo permitir que voc execute
tarefas administrativas em um servidor
SQL Server utilizando, por exemplo, o
Internet Explorer ou Mozilla Firefox e
podendo assim acessar a ferramenta
de qualquer estao da sua rede. Na
verdade, como uma ferramenta Web,
voc pode acess-la at remotamente,
basta que para isso voc tenha acesso
rede interna da sua empresa atravs
da internet.

O artigo apresenta uma soluo para gerenciamento de bancos de dados do SQL Server a partir
de uma ferramenta que utiliza a Web como plataforma de execuo, chamada SQL Server Web Data
Administrator. O artigo descreve como instal-la,
configur-la e utiliz-la para o gerenciamento de
um banco de dados.

Para que serve?


Gerenciar bancos de dados sempre um desafio.
Problemas no escolhem hora para ocorrer. Nesse
contexto, ter conhecimento de uma ferramenta
que possibilita o gerenciamento de banco de dados
atravs da Web bastante importante, pois permite
a interveno de um DBA, quando necessrio, sem a
obrigao de estar fisicamente presente no servidor.
Com isso, ganhamos em praticidade e tempo para gerenciamento de bancos de dados no SQL Server.

Em que situao o tema til?


Este tema se torna til para profissionais e empresas
que precisam de um gerenciamento instantneo de
seus bancos de dados no SQL Server, e que podem
usufruir dos recursos de uma ferramenta que possibilita o gerenciamento de bancos de dados atravs
da Web, possibilitando o gerenciamento remoto dos
bancos de dados do SQL Server.

Edio 72 - SQL Magazine


SQL73.indb 29

29

25/02/2010 14:30:48

No artigo de hoje ser apresentada esta ferramenta, descrevendo passo-a-passo como realizar sua instalao e configurao, alguns de seus principais recursos e como us-la para
executar algumas tarefas bsicas de administrao.

Conhecendo o SQL Server Web Data Administrator


O SQL Server Web Data Administrator uma ferramenta
desenvolvida em ASP.NET e teve sua primeira verso liberada
em Abril/2004 no prprio site de download da Microsoft. A
primeira verso funcionava apenas com SQL Server 7 ou SQL
Server 2000, e era uma excelente alternativa para usurios que
possuam o SQL Server 2000 Desktop Engine (MSDE 2000),
isso porque diferente das demais edies do SQL Server 2000,
a edio Desktop Engine no possui nenhuma ferramenta
administrativa.
Com a chegada do SQL Server 2005, uma nova verso da
ferramenta passou a ser desenvolvida e disponibiliza atravs
do site CodePlax e agora tambm pode ser utilizada para
executar tarefas bsicas de administrao em qualquer edio
do SQL Server 2005.
Como voc ver no decorrer deste artigo, a instalao da
ferramenta bastante simples e uma vez configurada permite
que voc execute tarefas como:
Criar e editar bancos de dados no SQL Server 7/2000 e 2005
ou Microsoft SQL Server 2000 Desktop Engine (MSDE 2000) e
SQL Server 2005 Express.
Criar e executar consultas (queries) ad-hoc sobre os bancos
de dados e salv-las em seu disco rgido.
Executar comandos Transact-SQL.
Exportar e importar dados e estruturas de objetos.
Gerenciar logins, usurios e papis (roles).
Criar, editar, renomear e excluir tabelas.
Criar, editar e excluir stored procedures.
Visualizar e editar as propriedades dos bancos de dados.
Como se pode notar, a ferramenta possui muitas funcionalidades e permite que voc administre um servidor SQL Server
de forma bastante simples. Como uma ferramenta web, pode
inclusive ser uma tima alternativa para quem quer acessar o
SQL Server atravs da internet usando uma ferramenta Web
ou ainda simplesmente para acessar um servidor SQL Server
usando qualquer estao de uma rede e sem precisar instalar
as ferramentas administrativas do SQL Server nas estaes.

Microsoft .NET Framework 2.0.


Internet Explorer 5.5 ou superior.
Servidor de Aplicao (como o Internet Information Services
(IIS) ou Apache). Apesar de no consta nada sobre Apache na
documentao, acreditamos que ele tambm possa ser usado.
No entanto, iremos utilizar apenas o IIS neste artigo.
Ferramentas de conectividade do SQL Server 2000 SP4 ou
superior.
Neste artigo estaremos utilizando um servidor com Windows Server 2003 Service Pack 2, .NET Framework 2.0, Internet
Explorer 6.0 e Internet Information Services (IIS) 6.0.
Uma vez feito o download do arquivo zip citado anteriormente, execute a instalao seguindo os passos descritos
abaixo:
1. Uma vez que tenhamos garantida a configurao dos prrequisitos para instalao da ferramenta SQL Server Web
Data Administrator, localize o arquivo SqlWebAdmin.zip
(que voc j deve ter feito o download no site do CodePlex) e
extraia os arquivos para o caminho C:\SqlWebAdmin. Caso
voc ainda no esteja com o Internet Information Services
instalado, nos endereos abaixo voc encontra dois artigos
com um passo-a-passo para a instalao dos mesmos no
Windows Server 2003 e tambm no Windows XP:
- http://www.baboo.com.br/absolutenm/templates/content.asp?
articleid=9761: Instalando o IIS no Windows XP.
- http://imasters.uol.com.br/artigo/1345/servidores_windows/
configurando_o_iis_60: Instalando o IIS 6.0 no Windows
Server 20003.
2. Concluda a extrao dos arquivos, navegue pela estrutura de arquivos at encontrar a ltima pasta de nome
SqlWebAdmin. Clique com o boto direito sobre a pasta e
como apresentado na Figura 1, selecione a opo Properties
(Propriedades).

Instalando o SQL Server Web Data Administrator


Como ser demonstrado no decorrer deste tpico, a instalao
do SQL Server Web Data Administrator bastante simples e
inicia com o download do arquivo SqlWebAdmin.zip no portal
CodePlax no endereo http://www.codeplex.com/SqlWebAdmin/
Release/ProjectReleases.aspx. Porm, antes de iniciar a instalao
da ferramenta, a mquina onde esta ser instalada dever
satisfazer alguns requisitos como segue:
Windows Server ou Professional com SP4, Windows Server
2003 ou ainda Windows XP SP2 ou superior.

30
SQL73.indb 30

Figura 1. Selecionando a opo Properties da pasta SqlWebAdmin

SQL Magazine - Administrando o SQL Server com uma Ferramenta Web


25/02/2010 14:30:48

sql server

3. Na janela de propriedades da pasta SqlWebAdmin, selecione


a guia Web Sharing (Compartilhamento Web) e clique sobre a
opo Share this folder (Compartilhar esta pasta). Na janela Edit
Alias simplesmente selecione a opo Execute (includes scripts)
[Executar (inclui scripts)] e clique em Ok (Figura 2).

clique com o boto direito sobre a barra de tarefas do Windows e selecione a opo Propriedades (Properties) conforme
apresentado na Figura 5. Na janela de Propriedades da Barra de
tarefas e do menu Iniciar, selecione a guia Menu Iniciar, clique
sobre a opo Menu Iniciar clssico e depois sobre o boto
Personalizar... (Figura 6). Em Opes avanadas do menu Iniciar
(Figura 7) selecione a opo Exibir Ferramentas administrativas
e clique em OK para confirmar a configurao. A partir deste
momento o item Ferramentas Administrativas j dever estar
sendo apresentado no menu Iniciar Programas.

Figura 2. Opo Execute durante o compartilhamento da


pasta SqlWebAdmin

Neste momento a janela de propriedades da pasta SqlWeb


Admin estar semelhante apresentada na Figura 3. Aps
isso clique em Ok.

Figura 4. Janela de administrao do Internet Information Services (IIS)

Figura 5. Opo Propriedades na barra de tarefas do Windows

Figura 3. Criando um compartilhamento Web para a pasta SqlWebAdmin

4. Antes de comear a usar a ferramenta, ainda preciso


fazer algumas configuraes no IIS. Para isso, acesse o menu
IniciarProgramasFerramentas Administrativas e selecione
a opo Internet Information Services (IIS) Manager. Ser ento
aberta a janela principal de administrao do IIS que pode ser
vista na Figura 4.
Caso voc esteja utilizando o Windows 2000 Professional ou
Windows XP, pode ser que no encontre a opo Ferramentas
Administrativas no item de menu Programas. Neste caso,

Figura 6. Selecionando o boto Personalizar

Edio 72 - SQL Magazine


SQL73.indb 31

31

25/02/2010 14:30:48

porque voc no est com o Microsoft .NET Framework


2.0 instalado. Neste caso, instale o .NET Framework 2.0
e depois prossiga com a configurao. Caso necessrio,
voc pode fazer o download do .NET Framework 2.0 nos
seguintes links:
- htt p:// w w w.microsof t.com/dow nloads/details. aspx?
Fa mi lyI D = 0 8 5 6 e a c b - 4 3 62- 4 b 0 d - 8 e d d - a a b1 5 c 5 e 0 4 f 5
&DisplayLang=en: .NET Framework 2.0 32bits.
- htt p:// w w w.microsof t.com/dow nloads/details. aspx?
familyid=B44A0000-ACF8-4FA1-AFFB-40E78D788B00
&displaylang=en: .NET Framework 2.0 64bits.

Figura 7. Selecionando a opo de Ferramentas Administrativas

5. Aberta a janela principal do IIS, expanda o n que


contm o nome do seu computador (no caso deste artigo
SRVSQL2008). Em seguida, no n Web Service Extensions
selecione a extenso All Unknow ISAPI Extensions e depois
clique sobre o boto Allow (Figura 8). A extenso ISAPI
(IIS Application Program Interfaces) estende as habilidades
das pginas web e sua ativao um dos requisitos para
executar pginas ASP (Active Server Pages) no IIS 6.0.
Figura 9. Selecionando a opo Properties do site SqlWebAdmin

Figura 8. Ativando a extenso ISAPI no Internet Information Services

6. Aps a ativao da extenso, expanda o n Web Sites e tambm Default Web Sites. Como apresentado na Figura 9, clique
com o boto direito sobre a pasta SqlWebAdmin e selecione a
opo Properties (Propriedades).
7. Na janela de Propriedades do site, selecione a guia ASP.
NET e no campo ASP.NET version selecione a verso
2.0.50727 e clique sobre o boto Ok (Figura 10). Caso esta
verso no aparea como uma opo para voc, certamente

32
SQL73.indb 32

Figura 10. Configurando a verso do ASP.NET nas propriedades do site


SqlWebAdmin

Isso conclui a instalao e configuraes necessrias para a


utilizao da ferramenta.

SQL Magazine - Administrando o SQL Server com uma Ferramenta Web


25/02/2010 14:30:49

sql server

Trabalhando com o SQL Server Web Data


Administrator

Nota do DevMan 1

Uma vez que o SQL Server Web Data Administrator est


instalado e configurado corretamente, possvel acessar a ferramenta de qualquer estao de uma rede utilizando o Internet
Explorer e usando a URL http://nome_servidor/SqlWebAdmin/default.aspx, onde nome_servidor o nome do servidor
onde voc instalou o SQL Server Web Data Administrator.
Diante da janela de login (Figura 11), o processo de logon
exatamente igual ao executado pelo Query Analyzer do SQL
Server 2000 ou ainda o SQL Server Management Studio do SQL
Server 2005 (Nota DevMan 1). Ou seja, voc pode usar o modo
de autenticao SQL (usando um usurio do SQL Server) ou
ainda autenticao Integrada do Windows (usando um login
do Windows).
Para demonstrar a vocs a utilizao de alguns recursos da
ferramenta, utilizaremos uma estao com Windows Vista e
iremos nos conectar a uma instncia remota do SQL Server
2005 Express utilizando o login sa (administrador do SQL
Server). Quando digo instncia remota quero dizer que o
SQL Server 2005 Express est instalado em outra mquina da
minha rede, chamada WINXPDEV. Notem que neste cenrio
estamos utilizando trs mquinas diferentes, o SQL Server
Web Data Administrator est instalado em um servidor Windows Server 2003 SP2 de nome SRVSQL2008, o SQL Server
2005 Express est instalado sobre o Windows XP SP2 em uma
segunda mquina da rede que responde pelo nome WINXPDEV e estaremos utilizando ou acessando a ferramenta atravs
de uma terceira mquina que possui o Windows Vista SP1 e
responde pelo nome WINVISTA.
Ao abrir o Internet Explorer no Windows Vista e colocar a
URL http://srvsql2008/SqlWebAdmin/default.aspx, a pgina de
login do SQL Server Web Data Administrator carregada
e podemos ento entrar com os dados de conexo conforme
apresentada na Figura 11. No exemplo da Figura 11 estamos
estabelecendo uma conexo com o servidor SQL Server 2005
Express utilizando o login sa (administrador do SQL Server
Express).

Aps efetuar o login temos acesso pgina principal do SQL


Server Web Data Administrator (apresentada na Figura 12).
Nesta pgina podemos notar a presena de alguns menus do
lado esquerdo os quais permite a execuo de tarefas como:
Gerenciamento de Banco de Dados: opes para criar, consultar, editar e excluir banco de dados e seus respectivos objetos
(tabelas, views, procedures, usurios, roles, etc).
Importao de dados: permite importar dados e objetos de
um banco de dados a partir de arquivos de scripts .sql contendo
comandos Transact-SQL.
Exportao de dados: permite exportar dados e estruturas
dos objetos de um banco de dados selecionado salvando o
resultado como um arquivo de script .sql.
Gerenciamento de Segurana: permite gerenciar logins e
associar logins a fixed server roles, como por exemplo, tornar
um login administrador do SQL Server.

Figura 11. Janela de login do SQL Server Web Data Administrator com os
dados de logon

Figura 12. Janela principal do SQL Server Web Data Administrator

SQL Server Management Studio


SQL Server Management Studio uma ferramenta includa no SQL Server 2005 para
configurao, gerenciamento e administrao de todos os componentes do Microsoft SQL
Server. A ferramenta inclui editores de script e ferramentas grficas que trabalham com
objetos e funcionalidades do servidor.
Uma funcionalidade central do SQL Server Management Studio o Object Explorer, que
permite ao usurio consultar, selecionar e atuar sobre qualquer objeto do servidor.
A Microsoft criou tambm uma ferramenta grfica de configurao chamada SQL Server Management Studio Express (SSMSE) para o SQL Server Express. Assim como todos
os produtos Express da Microsoft, ela pode ser baixada gratuitamente. As limitaes da
ferramenta esto associadas impossibilidade de gerenciamento de Servios de Anlise
do SQL Server, Servios de Integrao, Notificao de Servios, Servios de Relatrio ou
Edio do SQL Server 2005 para dispositivos mveis.
A verso full do SQL Server Management Studio combina as funcionalidades do Enterprise Manager, Query Analyzer e Analysis Manager, includos nas verses anteriores do
SQL Server, em um nico ambiente. Alm disso, SQL Server Management Studio trabalha
com todos os componentes do SQL Server tais como Servio de Relatrio, Servio de Integrao, Edio compactada do SQL Server e Servio de Notificao.

Edio 72 - SQL Magazine


SQL73.indb 33

33

25/02/2010 14:30:49

A partir deste ponto, veremos alguns dos recursos oferecidos


pelo SQL Web Data Administrator.

Criando e Editando um Banco de Dados

SQL Server 2000 ou SQL Server Management Studio do


SQL Server 2005. No exemplo da Figura 17 demonstramos
a execuo de um script que cria a tabela TB_SQLMAG e
inclui trs novos registros, cria a procedure usp_sqlmag e

Para criar um banco de dados no Web Data Administrator,


basta selecionar o link Create new database, localizado no
canto superior direito na pgina de databases. Ao clicar sobre
o link, uma nova pgina ser apresentada solicitando que voc
informe um nome para o novo banco de dados. No exemplo
da Figura 13 estamos solicitando a criao do banco de dados
DB_SQLMAGAZINE.

Figura 13. Informando um nome para o novo banco de dados

Aps criar o novo banco de dados, voc notar a presena dos


menus Tables, Stored Procedures, Query, Properties, Users e Roles.
Estes menus tambm esto disponveis quando voc seleciona
um banco de dados na lista de databases apresentada na pgina
principal e atravs deles possvel executar tarefas como:
Criar, editar, renomear e excluir tabelas ou procedures.
Executar consultas ad-hoc e comandos Transact-SQL selecionando o menu Query.
Visualizar as propriedades do banco de dados e tambm
configurar a propriedade Automatically grow file tanto para o
arquivo de dados quanto para o arquivo de log. Esta opo
funciona exatamente como as opes que temos no Enterprise
Manager do SQL Server 2000 ou SQL Server Management
Studio do SQL Server 2005 permitindo que voc configure
os arquivos de dados e log do banco de dados para expandir
automaticamente na medida em que mais espao necessrio
para alocar os dados.
Criar, editar e excluir usurios ou database roles.
Editar databases roles e atribuir ou remover usurios das roles.
Na Figura 14 voc pode ver estes menus aps termos selecionado o banco de dados AdventureWorks.
Como um exemplo, para criar ou editar um stored procedure
(SP) existente basta selecionar o menu Stored Procedures.
Estando na pgina Stored Procedures (Figura 15), voc pode
criar uma nova SP clicando sobre o link Create new stored
procedure localizado no canto superior direito da pgina, ou
ainda editar ou excluir uma stored procedure utilizando os
links edit ou delete referente SP desejada. Na Figura 16
temos um exemplo de edio da SP GetOrdersSignedProc do
banco de dados AdventureWorks.
Atravs do menu Query voc tambm poder executar
suas consultas ou comando Transact-SQL da mesma forma
que os fazem nas ferramentas grficas Query Analyzer do

34
SQL73.indb 34

Figura 14. Menus Tables que permite a criao ou gerenciamento de


tabelas em um banco de dados

Figura 15. Pgina de gerenciamento de Stored Procedures do SQL Web


Data Administrator

Figura 16. Editando uma stored procedures no SQL Web Data Administrator

SQL Magazine - Administrando o SQL Server com uma Ferramenta Web


25/02/2010 14:30:50

sql server

logo em seguida executa a procedure sobre o banco de dados


DB_SQLMAGAZINE. Note que tambm existem opes para
voc salvar a query (Save Query) e carregar um arquivo de
script existente (Load Query). Observe que o resultado da
execuo da query apresentado logo abaixo do painel de
edio de cdigo.

Exportando e Importando Dados e Objetos


Duas funcionalidades tambm muito teis no SQL Server Web
Data Administrator so as opes para exportar e importar
dados e objetos de um banco de dados. Ao acessar o item Export
no menu SERVER TOOLS voc ser direcionado para a pgina
Export Database apresentada na Figura 19. Nesta pgina voc
pode selecionar um banco de dados e selecionar tambm o que
deseja exportar. possvel exportar apenas os scripts de criao
do database, tabelas e procedures ou ainda exportar tambm
os dados das tabelas em formato de INSERT.

Figura 17. Executando consultas no SQL Web Data Administrator

No menu Properties voc pode visualizar informaes sobre


as propriedades do banco de dados e ainda configurar as
opes de Automatically grow file para os arquivos de dados
e log de um banco de dados. Na Figura 18 temos a pgina
de propriedades para o banco de dados AdventureWorks.
Observe que por default a opo Automatically grow file est
ativada tanto para o arquivo de dados quanto para o de log.
Isso significa que na medida em que mais espao necessrio
para armazenar os dados, o SQL Server expande os arquivos
de dados e log automaticamente de acordo com o valor em
Megabytes e Percentagem configurados para os arquivos de
dados e log respectivamente.

Figura 18. Visualizando as propriedades do banco de dados


AdventureWorks

Figura 19. Pgina de exportao de dados e objetos do SQL Web Data


Administrator

Na Figura 20 exibido um exemplo com a exportao dos


objetos do banco de dados DB_SQLMAGAZINE. Note que no
exemplo a tabela TB_SQLMAG e seus respectivos dados e tambm a procedure usp_sqlmag so exportados para um arquivo
de extenso .sql.
Uma vez que voc possui um script Transact-SQL, voc pode
ento usar o menu Import para importar os scripts para dentro de
um banco de dados existente ou ainda importar um script completo
para criao de um banco de dados e seus respectivos objetos.
Para melhor exemplificar, na pgina de exportao de banco
de dados (Figura 20) exportamos o banco de dado DB_SQLMAGAZINE utilizando as opes default. Isso gerou um script
me permitindo criar um novo banco de dados com as mesmas
configuraes e objetos que o banco de dados DB_SQLMAGAZINE. Para mostrar a importao, vamos alterar o script apenas
substituindo o nome DB_SQLMAGAZINE por DB_SQLMAGAZINE2 e atravs do menu Import vamos executar a importao
do script criando assim um novo banco de dados de nome
DB_SQLMAGAZINE2. O resultado da execuo do script pode
ser visto na Figura 21.
Note que da mesma forma que possvel carregar um script
para criar um banco de dados completo, voc tambm pode usar
a opo de Import apenas para criar alguns objetos sobre um
banco de dados. Como exemplo, usamos a opo de Import para
importar um script para recriar a tabela TB_SQLMAG e a procedure usp_SQLMAG com o sufixo 2. Na Figura 22 podemos ver as
tabelas criadas no banco de dados DB_SQLMAGAZINE2.

Edio 72 - SQL Magazine


SQL73.indb 35

35

25/02/2010 14:30:51

Figura 20. Exportando os objetos e dados do banco de dados DB_SQLMAGAZINE

voc poder criar e editar logins, incluir ou remover os


papis de servidor do SQL Server (fixed server roles) e dar
acesso aos bancos de dados existentes. Na Figura 23 podemos ver a pgina de criao de logins durante a criao do
login user_sqlmag.

Figura 21. Criando uma cpia do banco de dados DB_SQLMAGAZINE


atravs da opo Import

Figura 23. Criando um login atravs do SQL Server Web Data Administrator

Figura 22. Visualizando as tabelas do banco de dados DB_SQLMAGAZINE2

Criando Logins e Usurios


O SQL Server Web Data Administrator tambm permite
que voc gerencie logins e usurios em um servidor SQL
Server. Selecionando o menu Security na pgina principal

36
SQL73.indb 36

Aps ter criado um login voc tambm poder acessar um


banco de dados e criar um usurio para o respectivo login,
permitindo assim que no futuro o usurio possa se conectar
ao banco de dados. Para fazer isso, voc deve selecionar um
banco de dados na lista de databases da pgina principal e
utilizar o menu User, selecionando ento o link Create new
user no canto superior direito da pgina Database User.
Como apresentado na Figura 24, durante a criao do usurio
voc tambm pode informar a quais databases roles o usurio
dever ser includo. Tarefa esta que tambm pode ser feita
selecionado o menu Roles.
No exemplo da Figura 24, o usurio user_sqlmag adiciondo
role db_owner, o que permite a este usurio executar qualquer tarefa sobre este banco de dados.

SQL Magazine - Administrando o SQL Server com uma Ferramenta Web


25/02/2010 14:30:52

sql server

A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!

Concluso

D seu voto sobre este artigo, atravs do link:

Como vimos no decorrer deste artigo, o SQL Server Web


Data Administrator uma tima alternativa para quem

www.devmedia.com.br/sqlmagazine/feedback

Edio 72 - SQL Magazine


SQL73.indb 37

sobre e
s

Figura 24. Criando um usurio com SQL Server Web Data Administrator

Feedback
eu

edio
ta

D seu feedback sobre esta edio!

D
s

possui um servidor SQL Server 7, 2000 ou ainda 2005 e no


tem acesso as ferramentas administrativas grficas que
acompanham o produto. Como vimos, com esta ferramenta
possvel executar praticamente todas as tarefas bsicas da
administrao de uma base de dados SQL Server e ainda
tem-se a grande vantagem de poder ser acessada via browser atravs de qualquer mquina de uma rede, isso sem
precisar instalar nas mquinas qualquer outra ferramenta
do SQL Server.
No entanto, existe um requisito muito importante que
devemos estar atento: no servidor onde instalarmos o SQL
Server Web Data Administrator preciso tambm instalar
as ferramentas de conectividades do SQL Server 2000 SP4
ou uma verso superior.

37

25/02/2010 14:30:53

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Compresso de dados no SQL Server


De que se trata o artigo?
O artigo aborda o tema de compresso de dados no
SQL Server 2005 e o novo recurso disponibilizado
pela verso 2008, descrevendo como utiliz-lo e
seu benefcios.

Q
Vladimir Michel Magalhes
vladimir_magalhaes@yahoo.com.br

Bacharel em Cincia da Computao pela Universidade Federal do Rio Grande do Norte (UFRN),
trabalhou durante vrios anos como instrutor
de informtica do Senac/RN e atualmente
trabalha como Analista de Banco de Dados da
Universidade Potiguar (UnP), alm de ser consultor de empresas, com foco na rea de banco
de dados. DBA certificado Microsoft em SQL
Server 2005 e 2008, alm de outras certificaes.
http://vladimir-magalhaes.spaces.live.com/

38
SQL73.indb 38

uando falamos em bancos de


dados, um assunto recorrente o espao utilizado para
armazen-los. Bancos de dados normalmente ocupam um grande espao de
armazenamento e no incomum ver
Administradores de Bancos de Dados
(DBAs) tendo que negociar mais espao
para garantir o crescimento das bases
sem problemas. O problema que, muitas vezes, no h espao disponvel, e
necessrio comprar mais discos, o que
representa um custo a mais para a empresa. Por mais que o custo por Gigabyte
tenha decrescido bastante nos ltimos
anos, a compra de novos discos sempre
representa um custo, e nenhum gestor
vai aceit-lo sem uma boa justificativa,
normalmente questionando se no h
uma forma de aperfeioar o uso do espao disponvel de forma que no seja
necessria uma nova compra.

Para que serve?


Comprimir os dados armazenados em um banco de
dados bastante til para se obter ganho de espao
e de desempenho, o que consiste em um dos principais desafios no gerenciamento de bancos de dados
com grande volume de dados.

Em que situao o tema til?


Em qualquer ambiente onde se deseje economizar espao de armazenamento do banco de
dados, a aplicao de recursos de compresso
de dados providos pelo SQL Server 2005 e 2008
se apresenta como uma alternativa interessante para minimizar tais problemas.

Bancos de dados em geral so bastante


passveis de compresso, visto a natureza repetitiva dos dados armazenados.
Outro ponto a considerar que com
a compresso h uma srie de outros
ganhos que podem ser conseguidos,
como o aumento de desempenho devido

SQL Magazine - Compresso de dados no SQL Server


25/02/2010 14:30:54

sql server

a menor quantidade de I/O, j que a quantidade de Bytes armazenados ser menor, alm de um menor espao utilizado
para os backups.
O SQL Server dispe de uma srie de recursos, desde a
verso 2005, que permitem fazer melhor uso do espao em
disco, garantido uma razovel economia. Ao longo deste
artigo conheceremos um pouco sobre estes recursos de
compresso de dados.

Compresso no SQL Server 2005


O SQL Server 2005 j dispunha de alguns recursos para
permitir a compresso de dados. Uma delas era a habilidade de comprimir dados utilizando a compresso NTFS
do Windows. Para utilizar tal recurso, voc deve mover os
dados que deseja comprimir para um arquivo de dados secundrio (normalmente arquivos .ndf) e configur-lo como
read-only (somente leitura). Voc pode at configurar todo
o banco de dados como somente leitura, o que permitiria
comprimir todos os arquivos de dados e at o arquivo de
log, o que normalmente s faz sentido quando se tem apenas
uma grande quantidade de dados histricos, pois h a perda
de desempenho inerente a qualquer forma de compresso,
devido ao processo de compresso/descompresso.
Outra forma de compresso presente na verso 2005, depois de aplicado o Service Pack 2, a compresso de dados
numeric/decimal, chamada de vardecimal. Para utilizar esta
forma de compresso, voc deve ativ-la no banco de dados
e ento em cada tabela nas quais deseja utilizar tal recurso.
O vardecimal funciona de forma semelhante ao varchar, s
que para dados numricos. Quando voc define o tamanho
mximo de um campo numeric/decimal, o SQL Server define
a quantidade de Bytes que o mesmo ir ocupar, independentemente do valor que armazenado. Imagine ento
que voc definiu um campo decimal(18,4). O SQL Server
definir um tamanho de 9 Bytes para cada registro deste
campo, quer voc utilize ele ou no. Caso voc armazene
neste campo o valor 12.3, que poderia ser armazenado em
um campo decimal(3,1) e que ocuparia 5 Bytes, voc estaria
desperdiando 4 Bytes por registro. Caso ento voc ative
a compresso atravs do vardecimal e armazene o mesmo
valor, este ocuparia 3 Bytes, ou seja, menos at que o decimal
puro, representando um ganho de 6 Bytes por registro.
Vale lembrar que o vardecimal no garantia de ganho de
espao. Dependendo da situao, este pode representar at
um aumento no espao utilizado, ento podemos recomendar um estudo mais aprofundado do mesmo e uma anlise
caso a caso antes de utilizar tal recurso.
Para testar a compresso NTFS, criaremos um banco
de dados com o nome de Compressao, de acordo com a
Listagem 1. Neste banco de dados, criaremos uma tabela
no FileGroup Secondary, que depois ser modificado para
read only. Veja que alm do arquivo de dados primrio
chamado Compressao1.mdf, criamos um arquivo de dados
secundrio, chamado Compressao2.ndf, que ser armazenado na unidade F:.

Listagem 1. Criando o banco de dados de exemplo e testando a compresso


NTFS
USE [master]
GO
CREATE DATABASE [Compressao] ON PRIMARY
( NAME = NCompressao1, FILENAME = ND:\Compressao1.mdf , SIZE =
51200KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10240KB )
LOG ON
( NAME = NCompressao_log, FILENAME = ND:\Compressao_log.ldf
, SIZE = 10240KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [Compressao] ADD FILEGROUP [SECONDARY]
GO
ALTER DATABASE [Compressao]
ADD FILE ( NAME = NCompressao2, FILENAME = NF:\Compressao2.
ndf , SIZE = 51200KB , FILEGROWTH = 10240KB ) TO FILEGROUP
[SECONDARY]
GO
INSERT INTO CompressaoNTFS (NOME) VALUES (TESTE 01);
GO
INSERT INTO CompressaoNTFS (NOME) VALUES (TESTE 02);
GO
INSERT INTO CompressaoNTFS (NOME) VALUES (TESTE 03);
GO
/*Torna o filegroup Secondary apenas leitura*/
ALTER DATABASE [Compressao] MODIFY FILEGROUP [SECONDARY] READ_
ONLY
GO

Agora iremos habilitar a compresso na unidade de disco F:,


onde se encontra o Filegroup Secondary. Para isso, primeiro
pare o servio do SQL Server. Depois, v at as propriedades
da unidade, clicando com o boto direito do mouse sobre a
mesma e depois na opo Propriedades.
Na janela que aparece (Figura 1), habilitamos a caixa Compactar este disco para economizar espao. Por fim, reinicie o servio
do SQL Server.

Figura 1. Ativando a compactacao de unidade NTFS

Edio 72 - SQL Magazine


SQL73.indb 39

39

25/02/2010 14:30:55

A Figura 2 mostra o arquivo de dados secundrio do banco


de dados na unidade NTFS com compresso ativada.

Listagem 3. Testando a compresso VarDecimal


/*Exibe o tamanho ocupado pela tabela, antes da compresso
VarDecimal*/
1. EXEC sp_spaceused CompressaoVarDecimal
2. GO
/*Exibe uma estimativa do tamanho da tabela caso seja ativada a
compresso VarDecimal */
3. EXEC sys.sp_estimated_rowsize_reduction_for_vardecimal
CompressaoVarDecimal
4. GO

Figura 2. Arquivo de dados em unidade com compresso NTFS ativada

Neste caso, no preciso fazer mais nada no SQL Server, visto


que a compresso controlada pelo Windows. importante
lembrar que nesse caso, no podemos alterar ou inserir novas
informaes na tabela.
Neste momento, para testarmos a compresso Vardecimal
criaremos uma nova tabela (CompressaoVarDecimal) com cinco
campos decimal, e vamos inserir alguns registros na tabela
atravs de um loop que gera nmeros randmicos. Os comandos podem ser vistos na Listagem 2.

/*Ativa a compresso VarDecimal no banco de dados*/


5. EXEC sp_db_vardecimal_storage_format Compressao, ON
6. GO
/*Ativa a compresso VarDecimal na tabela*/
7. EXEC sp_tableoption CompressaoVarDecimal, vardecimal
storage format, 1
8. GO
/*Exibe o tamanho ocupado pela tabela, aps a compresso
VarDecimal*/
9. EXEC sp_spaceused CompressaoVarDecimal
10. GO

A Figura 3 mostra os resultados da execuo dos comandos


da Listagem 3.

Listagem 2. Criando a tabela sem compresso


USE Compressao;
GO
CREATE TABLE CompressaoVarDecimal(
CODIGO INT NOT NULL IDENTITY(1,1) PRIMARY KEY,

VALOR1 DECIMAL(18,4) NOT NULL,

VALOR2 DECIMAL(18,4) NOT NULL,

VALOR3 DECIMAL(18,4) NOT NULL,

VALOR4 DECIMAL(18,4) NOT NULL,

VALOR5 DECIMAL(18,4) NOT NULL

) ON [PRIMARY];
GO
DECLARE @CONTADOR SMALLINT, @QUANTIDADE SMALLINT
DECLARE @MENOR TINYINT, @MAIOR TINYINT
SET
SET
SET
SET

@CONTADOR = 1;
@QUANTIDADE = 30000;
@MENOR = 1
@MAIOR = 99

WHILE @CONTADOR <= @QUANTIDADE


BEGIN
INSERT INTO CompressaoVarDecimal

(VALOR1,VALOR2,VALOR3,VALOR4,VALOR5)

VALUES

(

ROUND(((@MAIOR - @MENOR -1) * RAND()

ROUND(((@MAIOR - @MENOR -1) * RAND()

ROUND(((@MAIOR - @MENOR -1) * RAND()

ROUND(((@MAIOR - @MENOR -1) * RAND()

ROUND(((@MAIOR - @MENOR -1) * RAND()
)

Figura 3. Espao ocupado antes e depois de ativada a compresso


VarDecimal

+
+
+
+
+

@MENOR),
@MENOR),
@MENOR),
@MENOR),
@MENOR),

0)
0)
0)
0)
0)

+
+
+
+
+

0.1,
0.1,
0.1,
0.1,
0.1

ET @CONTADOR += 1;
S
END

Antes de ativar a compresso, vamos seguir alguns passos


descritos na Listagem 3. Primeiramente, vamos verificar o espao ocupado pela mesma utilizando a stored procedure (SP)
sp_spaceused (linha 1). Depois, iremos estimar o espao ocupado
pela tabela caso seja ativada a compresso Vardecimal, e comparar
este valor com o tamanho atual da tabela, com a SP sys.sp_estimated_rowsize_reduction_for_vardecimal (linha 3). Agora iremos ativar
a compresso Vardecimal no banco de dados, com a SP sp_db_vardecimal_storage_format (linha 5) e, em seguida, na tabela, com a SP
sp_tableoption (linha 7). Aps isso, vamos novamente verificar o
espao ocupado pela tabela, com a SP sp_spaceused (linha 9).

40
SQL73.indb 40

Veja que no primeiro resultado exibido que os dados da


tabela ocupavam originalmente um espao total de 1728 KB
(coluna data). Em seguida, o prximo resultado mostra que, em
mdia, cada registro da tabela ocupa 56 KB (coluna avg_rowlen_fixed_format) e que a estimativa de que depois de ativada
a compresso VarDecimal, cada registro ocupe 36 KB (coluna
avg_rowlen_vardecimal_format), o que coincide com a estimativa
feito no incio do artigo, com uma economia de 4 Bytes por
campo Decimal, que no nosso caso eram 5 (4 x 5B = 20B), e um
total de 20 Bytes de economia por registro.
Por fim, o terceiro resultado mostra o espao ocupado pela
tabela aps a ativao da compresso VarDecimal, com os dados
ocupando um total de 1192 KB (coluna data). Comparando-se
o espao ocupado antes e depois da ativao da compresso
VarDecimal, vemos uma economia de mais de 30%. Obviamente
este resultado pode variar dependendo da situao.
Um ponto importante que tambm deve ser levado em considerao ao se utilizar a compresso vardecimal que para todo tipo
de dados varivel, como o varchar por exemplo, para cada registro
armazenado na tabela, podem ser armazenados 2 Bytes de offset,

SQL Magazine - Compresso de dados no SQL Server


25/02/2010 14:30:56

sql server

que servem para indicar o comprimento daquela coluna em disco,


j que esta no possui um tamanho fixo. Alm disto, caso a sua
tabela tenha alguma coluna de tamanho varivel, o SQL Server
armazena 2 Bytes para indicar o nmero de colunas de tamanho
varivel da tabela. Ento, caso sua tabela no possua nenhuma
outra coluna varivel e voc adicione uma para tirar vantagem
do armazenamento varivel, leve em conta estes 2 Bytes extras
por registro. Isto tambm explica porque no faz sentido criar
uma coluna do tipo Varchar (2), j que apenas o espao gasto com
o offset ocuparia os mesmos 2 Bytes caso a coluna fosse Char(2),
sem contar os Bytes para armazenar o valor em si da coluna.

Compresso no SQL Server 2008


Com o SQL Server 2008, ambas as formas de compresso presentes no SQL Server 2005 continuam disponveis, mas h novas
formas que podem ser utilizadas: Row Compression (compresso
em nvel de registro) e Page Compression (compresso em nvel
de pgina), mas estas funcionalidades esto presentes apenas
nas edies Enterprise e Developer do SQL Server 2008.
Cada tabela, ndice ou partio pode utilizar o seu tipo de
compresso independente das outras, mas apenas um tipo de
compresso para cada uma.
Quando utilizando compresso de linha, o SQL Server 2008
armazena todos os tipos de dados de tamanho fixo (char,
smallint, integer, etc..) como se fossem tipos de dados variveis,
ou seja, ele utiliza a mesma estratgia do vardecimal para todos os tipos de dados de tamanho fixo. Por exemplo, se voc
utilizar um campo do tipo integer, que por padro ocupa 4
Bytes, mas armazenar neste campo o valor 2, que poderia ser
armazenado em um campo tinyint de 1 Byte, o SQL Server ir
ocupar apenas o 1 Byte necessrio. Vale lembrar que isto no
muda de forma alguma a forma de utilizao destes tipos de
dados, ento voc no precisa fazer qualquer alterao em sua
aplicao para tirar vantagem desta novidade. Outra diferena
que o offset necessrio para indicar o tamanho de um campo
de tamanho varivel ou de um campo de tamanho fixo, mas
com a compresso ativada, de apenas 4 bits para todas as
colunas de tamanho menor ou igual a 8 Bytes, evitando assim
o problema existente para campos Varchar(2), que foi citado anteriormente, ou seja, para o mesmo campo integer que citamos
agora a pouco, seriam gastos 1 Byte para armazenar o valor do
campo, mais outros 4 bits para o offset. Alm disto, com esta
forma de compresso, qualquer campo que esteja com o valor
NULL e qualquer campo numrico com o valor 0 no ocupam
nenhum espao em disco, o que em vrias situaes pode representar uma grande economia de espao. A Figura 4 mostra
um exemplo do funcionamento da compresso de linha.

Figura 4. Funcionamento da compresso de linha

J o mtodo de compresso de pgina minimiza a redundncia


dos valores em colunas em um ou mais registros dentro de uma
mesma pgina de dados. Isto feito utilizando duas tcnicas de
compresso: prefixo da coluna e dicionrio de pgina.
A tcnica de prefixo da coluna trata os padres de repetio no incio dos valores armazenados, o que para um
ndice na coluna nome, por exemplo, seria bem comum,
j que os valores so ordenados e provavelmente seriam
similares. Imagine ento que voc tem uma coluna que est
em uma mesma pgina de dados e possui os valores Maria
Antnia, Maria dos Santos, Maria Santos, Maria,
Mario e Mario de Santos. Como podemos perceber, os
prefixos dos valores desta coluna so bem redundantes.
Neste caso, o que provavelmente iria ocorrer era a definio
de um prefixo Mari que seria armazenado em um local
chamado CI Structure, e os registros apontando para este
prefixo da seguinte forma: 1a Antnia, 1a dos Santos, 1
Santos, 1a, 1o e 1o de Santos (no obrigatoriamente
desta forma, isto um exemplo e tudo depende dos dados
existentes na pgina). Um exemplo deste funcionamento
pode ser visto na Figura 5.

Figura 5. Funcionamento da tcnica de prefixo de coluna

J a tcnica de dicionrio de pgina basicamente um dicionrio criado tambm na CI Structure, onde so armazenados
os valores com certa repetio dentro da coluna. O dicionrio
de pgina construdo em cima da estrutura de prefixos da
coluna, o que levar a uma situao onde provavelmente haver valores do dicionrio apontando para valores de prefixo
de coluna. Um exemplo deste funcionamento pode ser visto
na Figura 6.

Figura 6. Funcionamento da tcnica de dicionrio de pgina

Edio 72 - SQL Magazine


SQL73.indb 41

41

25/02/2010 14:30:56

Utilizando ento a mesma coluna do exemplo anterior,


terminaramos com algo similar ao seguinte: 2 Antnia,
2 dos 3, 1 3, 2, 4 e 4 de 3, onde foram criadas 3
palavras no dicionrio desta pgina, com o 1 representando o prefiro Mari, o 2 representando 1a, o 3
representando Santos e o 4representando 1o. Vejam
que, como esperado, o resultado do processamento com
a tcnica de prefixo de coluna, como 1a (Maria) e 1o
(Mario), sofreu nova compresso com a tcnica de dicionrio de pgina.
Uma vantagem interessante destes novos mtodos de
compresso comparados a compresso NTFS que diferentemente deste ltimo, os dados vo para a memria
com compresso, permitindo assim manter uma maior
quantidade de dados em cache, com a mesma quantidade de
memria, diminuindo assim o I/O, como mostra a Figura 7,
retirada de um artigo da HP sobre o assunto.

Listagem 4. Criando a tabela para os testes


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.

USE Compressao;
GO
CREATE TABLE Compressao(
C
ODIGO INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
N
OME CHAR(50)
);
GO
DECLARE @QUANTIDADE INT, @CONTADOR INT
DECLARE @NOME CHAR(50)
SET @CONTADOR = 1;
SET @QUANTIDADE = 30000;
WHILE @CONTADOR <= @QUANTIDADE
BEGIN
SET @NOME = (

MARI

+ CHAR(64+(@CONTADOR%26)) + CHAR(64+(@CONTADOR%26))

+ SANTOS

+ CHAR(64+(@CONTADOR%26)) + CHAR(64+(@CONTADOR%26))
);
I
NSERT INTO Compressao (NOME) VALUES (@NOME);
S
ET @CONTADOR += 1;
END;

/*Exibe o tamanho ocupado pela tabela, antes da compresso */


23. EXEC sp_spaceused Compressao
24. GO

Listagem 5. Testando a compresso de Linha (ROW)


1. USE Compressao;
2. GO
/*Fora o Rebuild da Tabela, ativando a compresso de Linha*/
3. ALTER TABLE Compressao REBUILD WITH (DATA_COMPRESSION = ROW);
4. GO
/*Exibe o tamanho ocupado pela tabela, aps a compresso de
Linha*/
5. EXEC sp_spaceused Compressao
6. GO

Figura 7. Nmero de leituras fsicas com e sem a compresso

A Listagem 4 mostra os comandos necessrios para criar a


tabela que utilizaremos em nossos exemplos (Linhas 3 a 6).
Nesta mesma listagem, esto os comandos com os quais
inserimos 30000 registros na tabela (Linhas 8 a 22), propositalmente com bastante redundncia, para servirem
de base para os testes. Por fim, utilizamos novamente a
SP sp_spaceused para verificar o tamanho da tabela.
A Figura 8 mostra o tamanho da tabela antes da ativao
da compresso.

Figura 9. Tamanho ocupado pela tabela depois de ativada a compresso


de linha

Neste caso, houve um ganho de mais de 50% (de 1880KB para


832 KB coluna data) no espao ocupado. Obviamente, este
resultado foi obtido devido grande taxa de repetio gerada
pelo script de insero de dados, mas o que tambm no quer
dizer que altas taxas de compresso possam ser obtidas.
A Listagem 6 mostra um script semelhante ao anterior,
mas agora ativando a compresso de pgina (linha 3) e novamente verificando o tamanho da tabela aps a compresso
(linha 5).
Listagem 6. Testando a compresso de Pgina (PAGE)
1. USE Compressao;
2. GO

Figura 8. Tamanho ocupado pela tabela antes da compresso

Vejamos agora na Listagem 5 como utilizar a compresso de


pgina. Nele mostramos como ativar a compresso (linha 3)
e depois verificamos novamente o tamanho da tabela
(linha 5).
A Figura 9 mostra o tamanho da tabela depois da compresso de linha (coluna data).

42
SQL73.indb 42

/*Fora o Rebuild da Tabela, ativando a compresso de Pgina*/


3. ALTER TABLE Compressao REBUILD WITH (DATA_COMPRESSION = PAGE);
4. GO
/*Exibe o tamanho ocupado pela tabela, aps a compresso de Pgina*/
5. EXEC sp_spaceused Compressao
6. GO

A Figura 10 mostra o tamanho da tabela depois de ativada


a compresso de pgina (coluna data).

SQL Magazine - Compresso de dados no SQL Server


25/02/2010 14:30:56

sql server

Vejam que neste caso houve um ganho de mais de 80% (de


1880KB, valor da coluna data na Figura 8, para 344 KB coluna data da Figura 10) no espao ocupado. Novamente, este
resultado foi obtido devido grande taxa de repetio gerada
pelo script de insero de dados, mas taxas bem razoveis
de compresso tendem a ser obtidas.

Figura 10. Tamanho ocupado pela tabela depois de ativada a compresso


de pgina

Consideraes e restries ao utilizar a compresso


de dados
Novamente, devemos analisar quando a compresso
ser benfica ou no. Apesar de diminuir o uso de espao em disco, a compresso aumenta o consumo de CPU,
principalmente a compresso por pgina. Alguns estudos
demonstram um aumento de 3% a 5%. Ento para cada
caso devemos analisar se o gargalo do servidor espao
em disco ou CPU. Caso seja CPU, pode no ser interessante
utilizar a compresso. Em caso contrrio, esta provavelmente trar mais ganhos do que perdas, apesar de que
em geral no recomendado habilitar a compresso em
tabelas que sejam freqentemente atualizadas.
Outros pontos importantes so que com a compresso
ativada, aumenta o tempo de Rebuild dos ndices e que
ela no funciona com campos Unicode. Para a primeira
situao, uma soluo fcil seria repensar os horrios
de manuteno dos ndices, j no segundo no h muito
que fazer.
A compresso tambm no feita automaticamente assim
que ativada devido ao impacto que isto poderia gerar em
um banco de dados em produo. A cada atualizao ou
insero de registros que o SQL Server faz a compresso
do registro ou da pgina alterada. Caso voc deseje forar
a compresso, basta fazer um Rebuild da tabela.
Alm disto, a compresso no pode ser utilizada se o
tamanho mximo do registro ultrapassar 8060 Bytes e
ela no pode ser utilizada junto com o recurso de Colunas Esparsas. Alm disso, ela no pode ser utilizada em
colunas do tipo BLOB (XML, MAX, TEXT, etc.), a no ser
que estas sejam armazenadas in-row, o que muitas vezes
no possvel, alm de ser um recurso que futuramente
ser removido do SQL Server.
No caso dos campos BLOB, as possveis solues seriam
fazer a compresso atravs da aplicao, o que fora uma
alterao da aplicao e tambm impede o uso das capacidades de pesquisa e atualizao parcial presentes no SQL
Server para campos BLOB. Uma outra e melhor soluo
utilizar o recurso de FileStream do SQL Server 2008 ou
armazenar os arquivos de dados em uma unidade NTFS
com compresso ativada.

Compresso no SQL Server 2008 R2


Apesar de ainda no estar em sua verso RTM (atualmente est
na verso CTP2), j h uma novidade relativa compresso na
verso 2008 R2 que veio a pblico. Nesta verso, ser possvel
utilizar a compresso em colunas NCHAR e NVARCHAR, apenas
com compresso de linha, no sendo possvel comprimir outros
tipos de colunas, nem mesmo do tipo NVARCHAR(MAX).
O SQL Server 2008 R2 implementa para os campos Unicode um
tipo de compresso chamada SCSU (Simple Compression Scheme
for Unicode Data ou esquema simples de compresso para dados
Unicode), que consiste em um tipo de compresso padro para
dados Unicode. Neste caso, a taxa de compresso depender do
idioma utilizado. A Tabela 1 mostra a taxa de compresso para
alguns idiomas, mas vale lembrar que para grande parte dos
idiomas europeus, o ganho ser de 50%.
Locale
Compression percentIdioma

Porcentagem de Compresso

Ingls

50%

Alemo

50%

Hindi

50%

Turco

48%

Vietnamita

39%

Japons

15%

Tabela 1. Exemplos de taxa de compresso de campos Unicode

A compresso Unicode habilitada ou desabilitada como parte


da compresso de linha ou pgina sem necessidade de nenhum
novo comando, bastando apenas ativar a compresso de linha ou
pgina na tabela que contem a coluna Unicode. Isto implica que
quem j utiliza a compresso de linha ou pgina precisar apenas
realizar um Rebuild da tabela para ter o benefcio da compresso,
ou apenas os novos registros sero comprimidos. Isso implica
tambm que todos os scripts existentes continuam funcionando
sem necessidade de nenhuma alterao.
Para alguns idiomas, como o coreano, a compresso no traz ganho algum. Ento neste caso, mesmo que voc habilite a compresso, caso o SQL Server 2008 R2 perceba que no haver ganhos
naquela coluna ele no aplicar a compresso internamente.
A Listagem 7 apresenta um exemplo de compresso em uma
tabela (CompressaoUnicode) com colunas Unicode.
Na Figura 11 podemos ver o resultado da compresso em
uma tabela contendo colunas Unicode.

Figura 11. Compresso em coluna Unicode

Edio 72 - SQL Magazine


SQL73.indb 43

43

25/02/2010 14:30:57

Listagem 7. Testando a compresso em colunas Unicode


USE Compressao;
GO
CREATE TABLE CompressaoUnicode(
CODIGO INT NOT NULL IDENTITY(1,1) PRIMARY KEY,

NOME NCHAR(50) -- utilizamos o tipo NCHAR, ao invz de CHAR

);
GO
DECLARE @QUANTIDADE INT, @CONTADOR INT
DECLARE @NOME CHAR(50)
SET @CONTADOR = 1;
SET @QUANTIDADE = 30000;
WHILE @CONTADOR <= @QUANTIDADE
BEGIN
SET @NOME = (

MARI

+ CHAR(64+(@CONTADOR%26)) + CHAR(64+(@CONTADOR%26))

+ SANTOS

+ CHAR(64+(@CONTADOR%26)) + CHAR(64+(@CONTADOR%26))

);
NSERT INTO CompressaoUnicode (NOME) VALUES (@NOME);
I

SET @CONTADOR += 1;

END;

Estimando os ganhos com a compresso


Normalmente, antes de comear a utilizar a compresso
estimamos os possveis ganhos da utilizao deste recurso,
alm de realizar alguns testes de impacto. O SQL Server fornece meios de fazer essa estimativa de ganhos, tanto no modo
grfico como tambm atravs de comandos T-SQL.
Para estimar a compresso atravs de comandos T-SQL, utilizamos a SP sp_estimate_data_compression_savings. Primeiro
desativamos a compresso da tabela (linha 3). Depois estimamos os ganhos da compresso com a compresso de Linha
(linha 5) e finalmente com a compresso de pgina (linha 11),
como mostra a Listagem 8.
Listagem 8. Estimando a compresso
1. USE Compressao;
2. GO
/*Fora o Rebuild da Tabela, desativnado a compresso */
3. ALTER TABLE Compressao REBUILD WITH (DATA_COMPRESSION = NONE);
4. GO
/*Estimando a compresso de Linha*/
5. EXEC sp_estimate_data_compression_savings
6.
@index_id = 1, --tipo de indce, no caso, Clustered
7.
@partition_number = 1, --Partio a ser comprimida, no
caso, 1 para tabela no particionada
8.
@schema_name = dbo, --schema
9.
@object_name = Compressao, --nome do objeto a ser
comprimido
10.
@data_compression = ROW --tipo de compresso, no
caso linha
/*Estimando a compresso de Pgina*/
11. EXEC sp_estimate_data_compression_savings
12.
@index_id = 1, --tipo de indce, no caso, Clustered
13.
@partition_number = 1, --Partio a ser comprimida,
no caso, 1 para tabela no particionada
14.
@schema_name = dbo, --schema
15.
@object_name = Compressao, --nome do objeto a ser
comprimido
16.
@data_compression = PAGE --tipo de compresso, no
caso pgina

Neste exemplo, estimamos a compresso com a tabela


utilizada nos exemplos anteriores. O resultado est apresentado na Figura 12. A coluna size_with_requested_compression_setting(KB) exibe o tamanho estimado com o tipo

44
SQL73.indb 44

/*Exibe o tamanho ocupado pela tabela, antes da compresso


Unicode*/
EXEC sp_spaceused CompressaoUnicode
GO
/*Fora o Rebuild da Tabela, ativando a compresso Unicode atravs
da compresso de Linha*/
ALTER TABLE CompressaoUnicode REBUILD WITH (DATA_COMPRESSION =
ROW);
GO
/*Exibe o tamanho ocupado pela tabela, aps a compresso de
Linha*/
EXEC sp_spaceused CompressaoUnicode
GO
/*Fora o Rebuild da Tabela, ativando a compresso Unicode atravs
da compresso de Pgina*/
ALTER TABLE CompressaoUnicode REBUILD WITH (DATA_COMPRESSION =
PAGE);
GO
/*Exibe o tamanho ocupado pela tabela, aps a compresso Unicode
*/
EXEC sp_spaceused CompressaoUnicode
GO

de compresso selecionado. A estimativa neste caso foi bem


razovel, visto os valores exibidos (832KB, como visto na
coluna data da Figura 9, x 848KB para compresso de linha e
344KB, como visto na coluna data da Figura 10, x 360KB para
compresso de pgina).
Algumas pessoas questionam o fato de no poderem estimar
os ganhos da compresso com outras edies que no seja a
verso Enterprise antes de decidir pela compra da mesma. Para
isso, aconselhado utilizar a verso Developer para realizar os
testes e tomar a deciso.

Benchmarks de Casos Reais


A equipe da Storage Engine do SQL Server divulgou alguns
nmeros fornecidos por clientes e tambm de pesquisas feitas
por terceiros. Eles do uma viso bem interessante do quanto
se pode ganhar com a compresso e a que custo.
No endereo http://blogs.msdn.com/sqlserverstorageengine/archive/2009/08/16/update-on-data-compression-in-sqlserver-2008-rtm.aspx possvel encontrar este e muitos outros
resultados sobre ambientes onde foi utilizada a compresso,
que esto resumidos nas Tabelas 2 e 3.
Ganho de espao com a compresso

Notas

70%

PAGE. Aplicao de Data Warehouse.

40%

PAGE. Aplicao Web OLTP.

62%

PAGE. Aplicao de Data Warehouse.

38%, 21%

PAGE, ROW.

80%, 50%

PAGE, ROW.

52%

PAGE.

50%, 15%

PAGE, ROW.

81%

PAGE. Aplicao ERP.

35%

PAGE.

Tabela 2. Ganho de espao com a compresso

SQL Magazine - Compresso de dados no SQL Server


25/02/2010 14:30:57

sql server

Figura 12. Estimando os ganhos com a compresso

40%-60%

2% - 3%

PAGE. Grande quantidade de consultas em intervalo sequencial.


Aplicao DW (Grande volume de IO)
PAGE. 500 usurios, 1500 Transaes / sec. OLTP com algumas
consultas para relatrios.
PAGE. Grande quantidade de insert, update e delete, que leva a
um aumento no uso de CPU. Uma melhor escolha teria sido a
escolha de ROW Compression.
PAGE. Aplicao OLTP.

3%

PAGE. Aplicao ERP transaes pequenas.

1%
11%

Tabela 3. Ganho de performance com a compresso

Concluso

Links
Vardecimal
http://msdn.microsoft.com/en-us/library/bb508963(SQL.90).aspx
Blog do time do SQL Server Storage Engine
http://blogs.msdn.com/sqlserverstorageengine/archive/2009/08/16/update-on-datacompression-in-sql-server-2008-rtm.aspx
Criando tabelas e ndices com compresso
http://msdn.microsoft.com/en-us/library/cc280449.aspx
Estimando os ganhos com a compresso
http://msdn.microsoft.com/en-us/library/cc280574.aspx
SQL Server 2008 R2
http://www.microsoft.com/sqlserver/2008/en/us/r2.aspx

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!

Feedback
eu

D seu voto sobre este artigo, atravs do link:


www.devmedia.com.br/sqlmagazine/feedback

Edio 72 - SQL Magazine


SQL73.indb 45

sobre e
s

O recurso de compresso pode trazer enormes ganhos,


principalmente na economia de espao em disco. Considerando a situao atual dos bancos de dados, com a chamada
exploso dos dados, com bancos de dados cada vez maiores,
Very Large DataBases (VLDBs) e o crescente armazenamento
de dados binrios, este recurso pode ser realmente til, desde
que utilizado nas situaes corretas.
Muitas vezes apenas a economia de espao em disco que
feita mais do que o suficiente para justificar a compra de

uma licena do SQL Server Enterprise Edition, permitindo


que voc usufrua de todos os outros recursos que esta edio
oferece, alm da compresso.

D
s

Notas
PAGE. Aplicao Web OLTP. Grande nmero de transaes.

edio
ta

Impacto na performance
5%

45

25/02/2010 14:30:58

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Oracle Performance Diagnostics & Tuning

m assunto de grande interesse


tratando-se do SGBD Oracle o
famoso Tuning, ou como prefiro
chamar, Performance Diagnostics & Tuning.
Prefiro utilizar este nome porque mais
importante que o ajuste o diagnstico.

Os mtodos antigos

Ricardo Portilho Proni


portilho@profissionaloracle.com.br
http://portilho.profissionaloracle.com.br

Com cerca de 20 anos de experincia profissional, Ricardo Portilho Proni Oracle ACE, e
j trabalhou em grande parte dos maiores
bancos de dados Oracle do Brasil.
atualmente o Team Leader do CES - Centro de Excelncia Solvo, unidade dedicada
s atividades de consultoria, arquitetura,
pr-venda e suporte 3o. Nvel da Solvo S/A,
empresa especializada na implementao
e suporte de ambientes de misso crtica e
atuao em toda a Amrica Latina.
Tambm Conselheiro do GPO, foi palestrante do V ENPO sobre Load Balance em RAC.
Possui as certificaes OCP 10g, OCE RAC,
OCE Linux, MCP, MCDBA, MCTS: SQL Server
2005, Certified MySQL DBA, e IBM DB2 Certified Database Associate.

46
SQL73.indb 46

Antes de lembrar dos antigos mtodos


de Performance Diagnostics & Tuning,
gostaria de dizer aos leitores que trago
uma boa notcia: Performance Diagnostics
& Tuning fcil.
Gosto de dizer isso a quem me pergunta
sobre Performance Diagnostics & Tuning,
pois este assunto foi por muito tempo
envolto em grande mistrio, sendo dominado apenas pelos mais experientes
profissionais em banco de dados Oracle.
Esta imagem do Performance Diagnostics
& Tuning foi fixada, na minha opinio,
pelos antigos mtodos adotados (entre meados dos anos 80 e incio dos anos 90) pelos
prprios DBAs, e que eram recomendados
em manuais e livros, e praticados pelos
prprios consultores da Oracle.
O antigo mtodo consistia geralmente
em seguir um Checklist, onde o DBA

De que se trata o artigo?


Este artigo trata do mtodo de diagnstico de problemas de desempenho em banco de dados Oracle
baseado em tempo.

Para que serve?


Para identificar, rapidamente e com preciso, qual o
gargalo que est restringindo o desempenho de uma
aplicao que utiliza um banco de dados Oracle.

Em que situao o tema til?


Quando o desempenho de uma aplicao que utiliza um banco de dados Oracle no satisfatrio

deveria verificar vrios itens, e vrios


indicadores conhecidos como Hit Ratios
(Buffer Cache Hit Ratio e Library Hit Ratio
eram os principais, dentre muitos).
Esta lista de itens que eram verificados
deve ser bem conhecida para a maioria
dos leitores: o consumo de processamento, memria, I/O e rede do sistema
operacional, o uso da SGA e PGA, a
fragmentao de tabelas e ndices,
a quantidade de sesses e cursores,
eram alguns entre centenas de outros
indicadores.

SQL Magazine - Oracle Performance Diagnostics & Tuning


25/02/2010 14:30:59

Oracle

O jogo era o seguinte: verificar a maior quantidade possvel de


indicadores, elaborar uma teoria sobre a lentido baseada neles,
e alterar algo que teoricamente melhore um ou mais destes indicadores, e medir novamente para ver se as alteraes surtiam
o efeito esperado. Mais do que isto, o DBA esperava que suas
alteraes no piorassem ainda mais o cenrio.
Em particular, o Buffer Cache Hit Ratio (que a proporo de
leituras que so feitas no Cache de dados da instncia Oracle, ao
invs do disco fsico do sistema operacional) era mais atentamente
observado pelos DBAs. Geralmente, se este estava abaixo de 90%, o
DBA aumentava o parmetro DB_CACHE_SIZE at onde era possvel, e verificava se o nmero de leituras nos discos diminua. Esta
tcnica, embora muito empregada at hoje, fundamentalmente
falha, pois o que o Oracle considera uma leitura fsica, pode no
ser para o sistema operacional, pois este tem seu prprio Cache
para o filesystem, assim como os discos rgidos, ou at mesmo o
Storage pode ter o seu.
Uma alternativa a este mtodo, executada por DBAs menos
experientes (ou mais desesperados) era analisar os parmetros
atuais do Oracle (so centenas, como voc deve saber), identificar um ou mais deles que teoricamente tem relao com a
lentido verifica, e ento alter-los, e observar o resultado.
Um mtodo comum tambm era o de, atravs de utilitrios do sistema operacional (como o top no Linux, ou topas no AIX), observar
qual processo de usurio consumia mais recursos, identificar o SQL
que este est fazendo, e tentar elaborar alguma melhoria nele.
Outra tcnica de Performance Diagnostics & Tuning muito empregada era adicionar hardware: se o banco de dados era considerado
lento, aumentava-se a memria, e a SGA (Nota DevMan 1) (e/ou
a PGA, que a rea de memria dos processos de usurio), ou at
mesmo a quantidade de processadores, at que o desempenho
ficasse satisfatrio. Infelizmente, para infelicidade de quem comprou e pagou pelo upgrade, nem sempre isto acontecia. Alis, h
casos onde aumentar os recursos de hardware piorou o cenrio.
Citei todos estes mtodos no tempo passado, mas vejo todos
muito utilizados at hoje. Reconheo que todos estes mtodos,
que fique bem claro, funcionavam e ainda funcionam, e que os Hit
Ratios no so de maneira alguma inteis, apenas incompletos. O
grande problema que todos estes mtodos dependiam completamente da experincia do profissional, e de alguma sorte.

O mtodo correto
Antes de executar um ajuste no SGBD Oracle, em resposta a
um problema de desempenho, devemos ter um diagnstico correto. Sem um correto diagnstico, no faz sentido prosseguir.
O desempenho de processos computacionais medido por velocidade. Quanto mais rpido, melhor o desempenho. E quando
se trata de velocidade, o desempenho s pode ser medido pelo
TEMPO. O tempo a nica constante onde podemos nos basear
sobre o desempenho de um processo computacional.
Portanto, para um correto diagnstico de um problema de
desempenho, deve-se saber onde o tempo gasto.
Finalmente, para saber-se onde o tempo gasto no Oracle,
no h uma forma mais direta que observar os Wait Events
(Eventos de Espera).

Nota do DevMan 1
SGA
System Global Area (SGA) uma terminologia usada no SGBD Oracle que representa uma rea de memria compartilhada responsvel por armazenar todas as
informaes referentes aos processos do Oracle. Essa rea dividida em vrias outras reas de memria que cada instncia do banco de dados ocupa no SGA.

Os Wait Events so eventos de espera por recursos computacionais, fsicos (discos rgidos, memria, rede, etc.) ou lgicos
(latches, locks, etc.). Estes recursos so limitados, e so os nicos
limitadores do desempenho de um comando SQL. Se no houvesse espera por recursos computacionais, todos os comandos
SQLs seriam finalizados instantaneamente.
Os Wait Events do Oracle so implementados pela OWI, a
Oracle Wait Interface. Esta implementao mede as esperas
diretamente do kernel do Oracle, e no nova, foi introduzida
na verso 7.0.12. Desde ento, os Wait Events monitorados pela
OWI cresceram consideravelmente, de 104 Wait Events na 7.0.12,
para 220 no 8i, 400 no 9i, e mais de 800 no 10g. Este progresso
mostra como a prpria Oracle acredita e investe neste mtodo
de diagnstico de problemas de performance.
Sabem aquela telinha bonita de desempenho do Enterprise Manager, com um grfico legal? Pois , aqueles grficos nada mais so do
que os Wait Events do Banco de Dados. Mas, como eu prefiro o bom
e velho SQL*Plus, este artigo ir demonstrar como encontrar os
gargalos do banco de dados sem a ajuda do Enterprise Manager.
Traando um paralelo da OWI com a vida real, pense em
quanto tempo voc leva para ir de So Paulo ao Rio de Janeiro,
de avio. Embora o tempo de vo leve menos que 30 minutos,
no tempo total a viagem completa pode levar umas 6 horas:
necessrio ir at o aeroporto, comprar a passagem, fazer o Check
In, despachar a bagagem, etc.
Prosseguindo com a metfora, o avio o comando SQL, enquanto todas as outras tarefas necessrias para se completar a
viagem so os Waits Events.
Ento, se voc precisa otimizar este tempo de 6 horas, onde
mais fcil e produtivo otimizar? O processo pode ser otimizado em vrios pontos: comprando-se previamente a passagem,
levando apenas bagagem de mo, fazendo outro caminho para
chegar ao aeroporto, etc. Mas otimizar o tempo de vo o mais
difcil (e caro, pode ser necessrio trocar o avio), e o que surtir
menos efeito no tempo total da viagem. Mesmo se comprarmos
um Concorde, o tempo total da viagem diminuiria de 6 horas
para 5 horas e 45 minutos.

Dynamic Performance Views


As principais Dynamic Performance Views (Visualizaes Dinmicas de Desempenho) que voc utilizar para fazer um diagnstico de desempenho com a OWI sero as descritas a seguir:
V$SESSION_WAIT: Esta a principal View da OWI, e mostra
com detalhes os Waits Events das sesses atuais. O nvel de detalhe excelente, e isto que permite um diagnstico preciso

Edio 72 - SQL Magazine


SQL73.indb 47

47

25/02/2010 14:30:59

do gargalo. Por exemplo, no evento db file sequential read,


exibido exatamente em qual arquivo est ocorrendo a leitura.
Como esta View muito precisa, e s tem com contedo o que
estava acontecendo exatamente no momento de sua consulta,
geralmente necessrio execut-la vrias vezes seguidas, para
poder observar o gargalo em tempo real;
V$SESSION_EVENT: Esta uma verso um pouco mais flexvel da V$SESSION_WAIT, pois mostra de forma acumulada
os maiores gargalos sofridos no passado recente das sesses
atuais, como demonstraremos mais adiante;
V$SYSTEM_EVENT: Esta View mostra todos os Waits Events
acumulados da instncia, desde que ela iniciou. Isto muito til
para executar uma primeira anlise em um ambiente que voc
no conhece, para se familiarizar sobre qual seria o problema
geral de lentido. Mas como acumulada, esta View pode dar
uma idia errada do problema de desempenho se utilizada sozinha, e deve ser utilizada em conjunto com as outras Views.
Vamos ento, na Listagem 1, analisar um banco de dados de
produo para definir onde est a lentido, para demonstrar
como utilizar a OWI.
Listagem 1. Comando SELECT para verificar os Wait Events das sesses atuais
SQL> SELECT SID, EVENT, SECONDS_IN_WAIT
FROM V$SESSION_WAIT W
ORDER BY SECONDS_IN_WAIT DESC;
SID
EVENT
SECONDS_IN_WAIT
---------- ----------------------------------------------------53
SQL*Net message from client
103370
46
SQL*Net message from client
102775
44
SQL*Net message from client
101402
23
SQL*Net message from client
99173
38
SQL*Net message from client
98231
72
SQL*Net message from client
95574
58
SQL*Net message from client
95060
33
SQL*Net message from client
93662
101
SQL*Net message from client
91972
57
SQL*Net message from client
91888
32
SQL*Net message from client
88720
208
SQL*Net message from client
88371

O evento SQL*Net message from client significa que o Oracle j


processou o que foi requisitado pela sesso, e est aguardando
que outro comando seja executado pelo usurio. Por exemplo,
pode ser uma sesso de SQL*Plus aberta, mas sem uso. Este um
dos Wait Events considerados Idle (Ociosos) pela documentao,
e portando, no afetam o desempenho do banco de dados. Veja
na Listagem 2 como obter da View V$EVENT_NAME (a coluna
WAIT_CLASS est disponvel no 10gR1 em diante) uma listagem
dos Wait Events ociosos.
Portanto, vamos excluir alguns deles de nossa anlise
para melhor claridade, e executar a consulta novamente
conforme Listagem 3.
importante salientar que, mesmo que a coluna SECONDS_IN_WAIT mostre o valor 0, estes Wait Events no devem
ser desprezados. Um mero segundo gasto em um destes Wait
Events muito, e em um sistema perfeitamente escalvel,
nenhum evento no ocioso seria visto neste SELECT.
Sabendo disso, e observando-se o resultado do SELECT, executado vrias vezes seguidas durante o perodo em que o sistema

48
SQL73.indb 48

era considerado lento pelo cliente, fica claro que o pior gargalo
do sistema causado pelo evento latch free (que ser melhor
explicado mais adiante), e em seguida o pior gargalo de I/O.
Para observar o SQL que est causando estas WAITs (troque
o 758 abaixo pelo SID que pegou no SELECT anterior), use
o SELECT demonstrado na Listagem 4.
Os Wait Events da Listagem 5 so relacionados a I/O (discos
rgidos) (Nota DevMan 2). Se estes Wait Events aparecerem
Listagem 2. Comando SELECT para verificar os Wait Events ociosos.
SQL> SELECT NAME
2 FROM V$EVENT_NAME
3 WHERE WAIT_CLASS = Idle
4 ORDER BY NAME;
NAME
---------------------------------------------------------------ASM background timer
auto-sqltune: wait graph update
class slave wait
cmon timer
DIAG idle wait
dispatcher timer
EMON slave idle wait
fbar timer
gcs remote message
ges remote message
HS message to agent
i/o slave wait
IORM Scheduler Slave Idle Wait
jobq slave wait
JOX Jit Process Sleep
JS external job
KSV master wait
LNS ASYNC archive log
LNS ASYNC dest activation
LNS ASYNC end of log
Logical Standby Apply Delay
LogMiner: builder idle
LogMiner: client waiting for transaction
LogMiner: generic process sleep
LogMiner: preparer idle
LogMiner: reader idle
LogMiner: reader waiting for more redo
LogMiner: slave waiting for activate message
LogMiner: waiting for processes to soft detach
MRP redo arrival
parallel recovery coordinator waits for slave cleanup
parallel recovery slave idle wait
parallel recovery slave next change
PING
pipe get
PL/SQL lock timer
pmon timer
pool server timer
PX Deq Credit: need buffer
PX Deq Credit: send blkd
PX Deq: Execute Reply
PX Deq: Execution Msg
PX Deq: Index Merge Close
PX Deq: Index Merge Execute
PX Deq: Index Merge Reply
PX Deq: Join ACK
PX Deq: kdcphc_ack
PX Deq: kdcph_mai
PX Deq: Msg Fragment
PX Deq: Parse Reply
PX Deq: Table Q Normal
PX Deq: Table Q Sample
PX Deq: Txn Recovery Reply
PX Deq: Txn Recovery Start
PX Deque wait
PX Idle Wait
rdbms ipc message
SGA: MMAN sleep for component shrink
shared server idle wait
simulated log write delay
single-task message
smon timer
Space Manager: slave idle wait
SQL*Net message from client
Streams AQ: deallocate messages from Streams Pool
Streams AQ: delete acknowledged messages
Streams AQ: emn coordinator idle wait
Streams AQ: qmn coordinator idle wait
Streams AQ: qmn slave idle wait
Streams AQ: RAC qmn coordinator idle wait
Streams AQ: waiting for messages in the queue
Streams AQ: waiting for time management or cleanup tasks
Streams capture: waiting for archive log
Streams fetch slave: waiting for txns

SQL Magazine - Oracle Performance Diagnostics & Tuning


25/02/2010 14:30:59

Oracle

Cont.: Listagem 2. Comando SELECT para verificar os Wait Events ociosos

Nota do DevMan 2

Streams: waiting for messages


VKTM Init Wait for GSGA
VKTM Logical Idle Wait
wait for unread message on broadcast channel
wait for unread message on multiple broadcast channels
watchdog main loop
WCR: replay client notify
WCR: replay clock
WCR: replay paused

I/O
I/O uma sigla para Input/Output, em portugus E/S ou Entrada/Sada.
Este termo utilizado quase que exclusivamente no ramo da computao
(ou informtica), indicando entrada (insero) de dados por meio de algum cdigo ou programa, para algum outro programa ou hardware, bem
como a sua sada (obteno de dados) ou retorno de dados, como resultado
de alguma operao de algum programa, consequentemente resultado de
algum input.

83 linhas selecionadas.

muito na V$SESSION_WAIT, certamente h um problema


global de I/O no banco de dados.
No temos espao para explicar todos estes Wait Events, mas dois
deles merecem ateno especial, pois so os que mais ocorrem:
db file scattered read - Um Full Table Scan (Varredura Completa
de Tabela) est ocorrendo: se este evento aparecer repetidamente na V$SESSION_WAIT, pode significar um SELECT que
teria um desempenho melhor com um ndice apropriado;
db file sequential read - Leitura de ndice: se este evento aparecer repetidamente na V$SESSION_WAIT para um mesmo
SID, pode significar leituras desnecessrias de ndice, como
aquelas foradas por um HINT, onde um Full Table Scan seria
melhor (sim, isto acontece muito).

As interfaces de entrada e sada so responsveis pela conexo entre


as vrias partes de um sistema computacional baseado na arquitetura de
Von-Neumann. Esta interface responsvel por conectar fisicamente o
processador e a memria do sistema ao barramento, tornando-se o terceiro
elemento do sistema computacional proposto.
Ao contrrio do que se pode pensar, a interface de entrada e sada no
s o conector fsico e sim tambm o responsvel pela comunicao lgica entre o barramento e o dispositivo. Essa funo de conexo foi basicamente desenvolvida para que seja possvel a comunicao entre vrios
dispositivos, fazendo com que a velocidade do barramento seja mais bem
aproveitada e ainda tanto os perifricos quanto os elementos essenciais
tenham programao/produo mais voltada ao seu desempenho, deixando a interconexo com as interfaces de entrada e sada.

Estes dois Wait Events tambm podem ser minimizados facilmente, aumentando-se o Cache (Nota DevMan 3) (parmetro DB_CACHE_SIZE), o que ir diminuir o acesso aos discos rgidos.
Agora, para termos uma viso mais completa das causas de
lentido do banco de dados, iremos fazer SELECTs nas outras
Listagem 3. Comando SELECT para verificar os Wait Events no ociosos das sesses atuais
SQL> SELECT SID, EVENT, SECONDS_IN_WAIT
2 FROM V$SESSION_WAIT W
3 WHERE EVENT NOT IN (SQL*Net message from client,
4
SQL*Net message to client,
5
pmon timer, smon timer,
6
rdbms ipc message, jobq slave wait,
7
rdbms ipc reply, i/o slave wait,
8
PX Deq: Execution Msg)
9 O
RDER BY SECONDS_IN_WAIT DESC;
SID
---------758
610
710
172
321
482
663
473
375
709
765
739
29
35
43
138
161
200
727
762
766
767
772
799
455
471
498
462

EVENT
SECONDS_IN_WAIT
--------------------------------------- --------------latch free
1
db file sequential read
1
latch free
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
buffer busy waits
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file sequential read
0
db file scattered read
0

548
604
655
669
677
722
152
48
266
213
223
400
405
458
352
366
374
387
408
447
668
715
504
516
580
607
221
333
322
262
257
241
232
228
175
167
658

db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db
db

file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file
file

scattered read
scattered read
scattered read
scattered read
scattered read
scattered read
scattered read
sequential read
scattered read
scattered read
scattered read
scattered read
scattered read
scattered read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read
sequential read

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

65 rows selected.

Edio 72 - SQL Magazine


SQL73.indb 49

49

25/02/2010 14:31:00

Listagem 4. Comando SELECT para verificar SQL executado por uma sesso.
SQL> SELECT A.SQL_TEXT
2 FROM V$SQLTEXT A, V$SESSION B
3 WHERE A.ADDRESS = B.SQL_ADDRESS
4
AND A.HASH_VALUE = B.SQL_HASH_VALUE
5
AND B.SID = 754
6 ORDER BY PIECE;

Views da OWI, como demonstrado na Listagem 6. Neste exemplo


vemos que realmente a View V$SYSTEM_EVENT nos enganaria se fosse observada isoladamente, pois mostra como maior
gargalo e evento undo segment extension, o que pode ter ocorrido
apenas em um momento isolado da vida da instncia. J a View
V$SESSION_EVENT confirma nosso diagnstico anterior de que
os maiores gargalos so causados por latches e I/O.
Os exemplos anteriores foram executados em um ambiente
de produo 9i. Vamos agora demonstrar na Listagem 7, como
simular um problema de desempenho e diagnostic-lo, em um
ambiente de testes isolado, um 11gR1 em Windows. E o mais
importante, iremos solucionar o problema.
Aps criar a tabela, irei inserir nomes de pessoas fictcias,
extrados de um arquivo texto, com cerca de 900.000 linhas.
Na Listagem 8 est o script Perl (Nota DevMan 4) que faz
estes INSERTs. Ele abre o arquivo texto, l linha a linha, separando os campos (que esto limitados por tabulaes), e usa o
primeiro campo na instruo de INSERT.
Perl uma linguagem muito til para administrao de bancos de
dados em geral, entre outras coisas. mais fcil de programar do
que Java ou C++, e muito mais poderosa do que Shell Script. Embora

Nota do DevMan 3
Cache
Na rea da computao, cache um dispositivo de acesso rpido, interno a um sistema, que serve de intermedirio entre um operador de um processo e o dispositivo de
armazenamento ao qual esse operador acede. A vantagem principal na utilizao de
uma cache consiste em evitar o acesso ao dispositivo de armazenamento - que pode
ser demorado -, armazenando os dados em meios de acesso mais rpidos.

Nota do DevMan 4
Perl
Perl uma linguagem de programao estvel e multiplataforma, usada em aplicaes
de misso crtica em todos os setores, sendo destacado o seu uso no desenvolvimento de
aplicaes web.Permite a criao de programas em ambientes UNIX, MSDOS,Windows, Macintosh, OS/2 e outros sistemas operacionais.Alm de ser muito utilizada para programao
de formulrios www e em tarefas administrativas de sistemas UNIX - onde a linguagem
nasceu e se desenvolveu - possui funes muito eficientes para manipulao de textos.
Perl uma das linguagens preferidas por administradores de sistema e especialmente
verstil no processamento de cadeias (strings),manipulao de texto e no pattern matching
implementado atravs de expresses regulares, alm de ser bastante adequada para o desenvolvimento de projetos utilizando uma metodologia gil.
A linguagem Perl j foi portada para mais de 100 diferentes plataformas e bastante
usada em desenvolvimento web, finanas e bioinformtica.

Listagem 5. Comandos SELECT para verificar os Wait Events de I/O


SQL> SELECT NAME
FROM V$EVENT_NAME
WHERE WAIT_CLASS = User I/O
ORDER BY 1;
NAME
---------------------------------------------------------------BFILE read
buffer read retry
cell multiblock physical read
cell single block physical read
cell smart file creation
cell smart index scan
cell smart table scan
cell statistics gather
Data file init write
Datapump dump file I/O
db file parallel read
db file scattered read
db file sequential read
db file single write
dbms_file_transfer I/O
dbverify reads
DG Broker configuration file I/O
direct path read
direct path read temp
direct path sync
direct path write
direct path write temp
external table misc IO
external table read
external table write
local write wait
Log file init write
read by other session
securefile direct-read completion
securefile direct-write completion
Shared IO Pool IO Completion

FROM V$EVENT_NAME
WHERE WAIT_CLASS = System I/O
ORDER BY 1;
NAME
---------------------------------------------------------------ARCH random i/o
ARCH sequential i/o
Archiver slave I/O
cell smart incremental backup
cell smart restore from backup
control file parallel write
control file sequential read
control file single write
db file parallel write
DBWR slave I/O
io done
kfk: async disk IO
ksfd: async disk IO
LGWR random i/o
LGWR sequential i/o
LGWR slave I/O
LNS ASYNC control file txn
Log archive I/O
log file parallel write
log file sequential read
log file single write
Network file transfer
recovery read
RFS random i/o
RFS sequential i/o
RFS write
RMAN backup & recovery I/O
RMAN Disk slave I/O
RMAN Tape slave I/O
Standby redo I/O
30 linhas selecionadas.

31 linhas selecionadas.
SQL> SELECT NAME

50
SQL73.indb 50

SQL Magazine - Oracle Performance Diagnostics & Tuning


25/02/2010 14:31:00

Oracle

Listagem 6. Comandos SELECT para verificar os maiores Wait Events das sesses atuais, e para verificar os Wait Events de toda a instncia
SQL> SELECT EVENT, SUM(TOTAL_TIMEOUTS)
2 FROM V$SESSION_EVENT
3 WHERE EVENT NOT IN (SQL*Net message from client,
4
SQL*Net message to client,
5
pmon timer, smon timer,
6
rdbms ipc message, jobq slave wait,
7
rdbms ipc reply, i/o slave wait,
8
PX Deq: Execution Msg)
9 GROUP BY EVENT
10 ORDER BY 2 DESC;
EVENT
SUM(TOTAL_TIMEOUTS)
---------------------------------------------- ------------------latch free
73351
io done
10958
undo segment extension
2509
enqueue
570
log file switch completion
232
log file sync
51
buffer deadlock
28
LGWR wait for redo copy
11
log buffer space
3
HS message to agent
0
SQL*Net break/reset to client
0
SQL*Net more data from client
0
control file sequential read
0
db file parallel write
0
db file sequential read
0
direct path read
0
process startup
0
log file single write
0
log file sequential read
0
log file parallel write
0
library cache load lock
0
imm op
0
direct path write (lob)
0
direct path write
0
direct path read (lob)
0
wait list latch free
0
row cache lock
0
refresh controlfile command
0
db file single write
0
db file scattered read
0
db file parallel read
0
control file parallel write
0
SQL*Net more data to client
0
async disk IO
0
buffer busy waits
0
35 rows selected.
SQL> SELECT EVENT, AVERAGE_WAIT, TOTAL_TIMEOUTS
2 F
ROM V$SYSTEM_EVENT
3 W
HERE EVENT NOT IN(SQL*Net message from client,
4
SQL*Net message to client,
5
pmon timer, smon timer,
6
rdbms ipc message, jobq slave wait,
7
rdbms ipc reply, i/o slave wait,
8
PX Deq: Execution Msg)
9 O
RDER BY TOTAL_TIMEOUTS DESC;
EVENT
AVERAGE_WAIT TOTAL_TIMEOUTS
-------------------------------------- ------------ -------------undo segment extension
0
8707775
latch free
2
1250783
enqueue
164
240635
PX Deq Credit: send blkd
86
138120
PX Idle Wait
194
30457
PL/SQL lock timer
202
15139
io done
1
10958
PX Deq: Table Q Normal
2
6152
virtual circuit status
2918
3887

Listagem 7. Comandos para criar a tabela de testes.


C:\Users\Ricardo>set ORACLE_SID=TEST11GR1
C:\Users\Ricardo>set ORACLE_HOME=c:\oracle\product\11.1.0\db_1
C:\Users\Ricardo>sqlplus SCOTT/TIGER
SQL*Plus: Release 11.1.0.7.0 - Production on Seg Ago 31 08:32:51 2009
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 Production
With the Partitioning, OLAP, Data Mining and Real Application
Testing option
SQL> CREATE TABLE PESSOAS (NOM_PESSOA VARCHAR2(255));
Tabela criada.
SQL> EXIT;

PX Deq Credit: need buffer


dispatcher timer
buffer deadlock
log file switch completion
PX Deq: Execute Reply
log file sync
log buffer space
inactive session
PX Deq: Signal ACK
buffer busy waits
slave TJ process wait
index block split
LGWR wait for redo copy
local write wait
kksfbc child completion
reliable message
control file heartbeat
wait list latch free
process startup
async disk IO
sbtinit
sbtbackup
direct path write (lob)
direct path read (lob)
direct path write
direct path read
db file parallel read
db file parallel write
db file single write
db file scattered read
db file sequential read
HS message to agent
SQL*Net break/reset to client
SQL*Net more data from dblink
SQL*Net message from dblink
SQL*Net more data from client
SQL*Net more data to dblink
SQL*Net more data to client
SQL*Net message to dblink
single-task message
PX Deq: Table Q Get Keys
PX Deq: Parse Reply
PX Deq: Msg Fragment
PX Deq: Join ACK
BFILE internal seek
BFILE read
BFILE open
BFILE get length
BFILE closure
library cache load lock
library cache pin
row cache lock
switch logfile command
log file parallel write
log file single write
log file sequential read
refresh controlfile command
control file parallel write
control file single write
control file sequential read
sbtclose2
sbtend
sbtinfo2
sbtinit2
sbtremove2
sbtwrite2
imm op

9
5815
0
12
3
1
24
98
0
0
1
1
0
11
2
66
391
1
3
0
15
80
0
0
0
0
2
3
0
0
1
0
0
0
0
3
0
0
0
4
1
0
0
0
0
0
0
0
0
8
3
0
3
0
0
3
0
0
1
0
1181
0
24
0
6
3
0

2536
1943
1927
850
651
208
121
109
55
50
27
20
11
7
5
2
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

76 rows selected.

no seja o escopo deste artigo, recomendo fortemente os leitores a


procurar mais sobre a Perl. Para utiliz-la no Windows, possvel
baixar gratuitamente a sute ActivePerl, da Active State.
Na Listagem 9 demonstro como executar este script e qual
a sada gerada.
Com o script finalizado, irei verificar onde ele gastou mais
tempo, como demonstrado na Listagem 10.
No h segredo: o maior tempo mdio deste caso
o log file switch completion. Consultando a documentao de Wait Events do RDBMS Oracle, vemos que este

Edio 72 - SQL Magazine


SQL73.indb 51

51

25/02/2010 14:31:00

Listagem 8. Script Perl para inserir nomes de um arquivo texto no banco de dados

Listagem 10. Comandos verificar os maiores Wait Events causados pelos Inserts

use strict;
use warnings;
use DBD::Oracle;

C:\Users\Ricardo>sqlplus / AS SYSDBA

system(time /T);
my $dbh = DBI->connect(dbi:Oracle:host=localhost;sid=TEST11GR1;p
ort=1523, SCOTT, TIGER, {RaiseError => 1, AutoCommit => 0});
my $sth;
open(PESSOAS, <person.tsv);
while ()
{
my $linha = $_;

chomp $linha;

my @pessoa = split(/\t/, $linha);

if ($pessoa[0] eq name) {next;};

$pessoa[1] =~ s/\/guid\///;

$pessoa[0] =~ s/\//g;

my $sql = INSERT INTO pessoas (nom_pessoa) VALUES

($pessoa[0]);
$sth = $dbh->prepare($sql);

$sth->execute();

}
$dbh->commit();
$sth->finish();
close PESSOAS;
system(time /T);
print INSERTs finalizados. Pressione ENTER.\n;
my $go = <>;
$dbh->disconnect();
exit;

Listagem 9. Comando para executar o Script Perl.


C:\temp>perl Insert_Oracle.pl
10:34
10:44
INSERTs finalizados. Pressione ENTER.\n

evento ocorre quando o Oracle j utilizou todos os Redo Logs


(Nota DevMan 5), da forma circular de sempre, e precisou
usar o primeiro novamente, mas as informaes que estavam
nele ainda no foram gravadas nos datafiles (pelo DBWR),
portanto, no podem ser sobrescristas, pois seriam necessrias em um eventual recover.
Finalizado o diagnstico, vamos ao ajuste. Para reduzir a
ocorrncia deste problema, j que o Oracle quer mais Redo
Logs, daremos Redo Logs a ele, como demonstrado na
Listagem 11.
Agora podemos executar o script novamente, como est na
Listagem 12.
Ora, o tempo continuou mesmo, mesmo reduzindo a maior
Wait Event, como est na Listagem 13.
A armadilha deste caso que os grandes tempos mdios
dos Wait Events de recursos fsicos (como log file sync, db file
sequential read e SQL*Net message from client) esconde o pssimo
tempo mdio de um Wait Event lgico: latch: shared pool. Coisas
lgicas devem ser mais rpidas que coisas fsicas! Neste caso,
20 milissegundos para acessar uma estrutura de memria
muito tempo, muito mais grave do que 900 milissegundos para
completar um switch.
Novamente consultando a documentao dos Wait Events
do RDBMS Oracle, vemos que este evento causado por compilaes excessivas de comandos SQL. Bom, vamos alterar
o script para utilizar SQLs reutilizveis, na verso Perl para
as variveis bind (que a forma utilizada pelo Oracle para
reutilizar comandos SQL similares), como demonstrado na
Listagem 14.
E ento podemos verificar o tempo resultante desta alterao
na Listagem 15.

52
SQL73.indb 52

SQL*Plus: Release 11.1.0.7.0 - Production on Seg Ago 31 10:24:48


2009
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 Production
With the Partitioning, OLAP, Data Mining and Real Application
Testing options
SQL> SET PAGESIZE 1000
SQL> SET LINESIZE 210
SQL> SELECT SID
FROM V$SESSION
WHERE USERNAME = SCOTT;
SID
137
SQL> SELECT EVENT, AVERAGE_WAIT, TOTAL_TIMEOUTS
FROM V$SESSION_EVENT
WHERE SID = 137
ORDER BY AVERAGE_WAIT;
EVENT ------------------------AVERAGE_WAIT TOTAL_TIMEOUTS
----------------------------- ------------ -------------latch: row cache objects
0
0
SQL*Net message to client
0
0
SQL*Net message from client
,02
0
latch: shared pool
,02
0
db file single write
,03
0
events in waitclass Other
,04
0
control file sequential read
,09
0
control file parallel write
,1
0
log file sync
,38
0
Data file init write
,39
0
db file sequential read
,5
0
db file scattered read
2,49
0
log file switch completion
4,84
0
13 linhas selecionadas.

O tempo caiu de 10 para 4 minutos, um resultado muito bom.


Vamos ver como ficaram muito menores os Wait Events desta
execuo na Listagem 16.

Concluso
Neste artigo abordamos como diagnosticar e solucionar problemas de desempenho de forma precisa, utilizando a Oracle Wait
Interface. Embora a OWI seja o nico mtodo que voc precisa conhecer para executar um excelente diagnstico, de forma alguma
este artigo abordou todos os seus aspectos. Recomendo que voc
leia atentamente a documentao da prpria Oracle a respeito.
Algumas recomendaes importantes baseadas em minha
experincia que quero deixar aos leitores:
Observe os Wait Events de todo sistema ao qual tiver
acesso, mesmo que este sistema tenha um bom desempenho.
Sabendo como se comportam os Wait Events de um sistema
com boa escalabilidade, voc saber identificar um sistema
ruim quando se deparar com um, mesmo que o cliente no
esteja reclamando dele;
Aps o ajuste de desempenho, se o tempo do comando
SQL ficou satisfatrio, o processo de diagnstico deve ser
encerrado. No caia na tentao de eliminar todos os Wait
Events simplesmente porque voc pode elimin-los. Voc no
conseguir eliminar todos os Wait Events, aceite isso. Faa
o que for necessrio para que o tempo de execuo fique
satisfatrio para o cliente, e siga em frente.

SQL Magazine - Oracle Performance Diagnostics & Tuning


25/02/2010 14:31:01

Oracle

Nota do DevMan 5
Redo Logs
No ambiente do Oracle, Redo logs so arquivos em um formato proprietrio
que registram um histrico de todas mudanas feitas ao banco de dados. Cada
arquivo de Redo Log consiste de registros de Redo. Um registro de Redo, tambm chamado de entrada de Redo, possui um grupo de vetores de mudanas,
e cada um descreve ou representa uma mudana feita a um nico bloco no
banco de dados.
Por exemplo, se um usurio atualiza (UPDATE) um valor de salrio em uma
tabela contendo dados referentes a empregados, o SGBD gera um registro de
Redo contendo vetores de mudanas que descrevem as alteraes ao bloco
do segmento de dados da tabela. E se o usurio confirma ento a alterao
(COMMIT), o Oracle gera outro registro de Redo e lhe atribui um System Change Number (Nmero de Alterao de Sistema), ou SCN.

Listagem 11. Comandos para adicionar Redo Logs


SQL> COL MEMBER FORMAT A70
SQL> SELECT * FROM V$LOGFILE;
GROUP# STATUS TYPE
MEMBER
IS_
------ ------ ------ -------------------------------------- --3
ONLINE C:\ORACLE\ORADATA\TEST11GR1\REDO03.LOG NO
2
ONLINE C:\ORACLE\ORADATA\TEST11GR1\REDO02.LOG NO
1
ONLINE C:\ORACLE\ORADATA\TEST11GR1\REDO01.LOG NO
SQL> ALTER DATABASE
ADD LOGFILE C:\ORACLE\ORADATA\TEST11GR1\REDO04.LOG
SIZE 1G;
Banco de dados alterado.
SQL> ALTER DATABASE
ADD LOGFILE C:\ORACLE\ORADATA\TEST11GR1\REDO05.LOG
SIZE 1G;
Banco de dados alterado.
SQL> ALTER DATABASE
ADD LOGFILE C:\ORACLE\ORADATA\TEST11GR1\REDO06.LOG
SIZE 1G;

Listagem 14. Script Perl para inserir nomes de um arquivo texto no banco
de dados utilizando variveis Bind
use strict;
use warnings;
use DBD::Oracle;
system(time /T);
my $dbh = DBI->connect(dbi:Oracle:host=localhost;sid=TEST11GR1
;port=1523?, SCOTT, TIGER, {RaiseError => 1, AutoCommit =>
0});
my $sth;
open(PESSOAS, <person.tsv);
while ()
{
my $linha = $_;
chomp $linha;
my @pessoa = split(/\t/, $linha);
if ($pessoa[0] eq name) {next;};
$pessoa[1] =~ s/\/guid\///;
$pessoa[0] =~ s/\//g;
my $sql = INSERT INTO pessoas (nom_pessoa) VALUES (?);
$sth = $dbh->prepare($sql);
$sth->execute($pessoa[0]);
}
$dbh->commit();
$sth->finish();
close PESSOAS;
system(time /T);
print INSERTs finalizados. Pressione ENTER.\n;
my $go = <>;
$dbh->disconnect();
exit;

Listagem 15. Comando para executar o Script Perl.


C:\temp>perl Insert_Oracle.pl
11:30
11:34
INSERTs finalizados. Pressione ENTER.\n

Listagem 16. Comandos verificar os maiores Wait Events causados pelos Inserts
SQL> SELECT EVENT, AVERAGE_WAIT, TOTAL_TIMEOUTS
2 FROM V$SESSION_EVENT
3 W
HERE SID = 142
4 O
RDER BY AVERAGE_WAIT;
EVENT
AVERAGE_WAIT TOTAL_TIMEOUTS
--------------------------- ------------ -------------latch: cache buffers chains
0
0
SQL*Net message to client
0
0
events in waitclass Other
,01
0
SQL*Net message from client
,02
0
log file sync
,64
0

Banco de dados alterado.

Listagem 12. Comando para executar o Script Perl


C:\temp>perl Insert_Oracle.pl
11:13
11:23
INSERTs finalizados. Pressione ENTER.\n

Se tiverem dvidas quanto a este artigo de Oracle Diagnostics


Performance & Tuning, ou qualquer outro assunto, no hesitem
em me escrever.

Listagem 13. Comandos verificar os maiores Wait Events causados pelos Inserts

8 linhas selecionadas.

Wikipedia
http://www.wikipedia.org/

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/sqlmagazine/feedback

D
s

Oracle On-Line Documentation


http://tahiti.oracle.com/

Edio 72 - SQL Magazine


SQL73.indb 53

Feedback
eu
sobre e
s

EVENT
AVERAGE_WAIT TOTAL_TIMEOUTS
---------------------------- ------------ -------------latch: cache buffers chains
0
0
latch: row cache objects
0
0
SQL*Net message to client
0
0
events in waitclass Other
0
0
latch: shared pool
,02
0
SQL*Net message from client
,02
0
db file sequential read
,57
0
log file sync
,92
0

Referncias

edio
ta

SQL> SELECT EVENT, AVERAGE_WAIT, TOTAL_TIMEOUTS


2 FROM V$SESSION_EVENT
3 WHERE SID = 142
4 ORDER BY AVERAGE_WAIT;

53

25/02/2010 14:31:01

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Usando CDC e Trigger em Auditorias no SQL


Server 2008
Conhecendo o recurso Change Data Capture
De que se trata o artigo?

S
Tulio Rosa
tulio.rosa@hotmail.com

Bacharel em Sistemas de Informao com


certificaes em MS SQL Server, trabalha
exclusivamente com banco de dados desde
2001, com conhecimentos das verses 6.5,
7, 2000, 2005 e 2008 do MS SQL Server,
experincia na administrao de banco de
dados em empresas de grande porte com
ambiente de alta disponibilidade, experincia em administrao de dados em fabrica
de software e atualmente trabalha como
DBA da Politec S/A e da Praxe Tecnologia.
http://tuliorosa.blogspot.com/

54
SQL73.indb 54

er abordado nesse artigo o Change Data Capture (CDC), recurso


que permite o registro de todas as
modificaes ocorridas nos dados das
tabelas. Ser demonstrada tambm a
utilizao de trigger para o registro das
alteraes nos dados das tabelas.
O CDC foi implementado no SQL
Server com o objetivo de identificar
os dados que sofreram alteraes. Sua
principal utilizao no processo de
ETL (Extrao Transformao e Carga),
processo responsvel por efetuar a carga
de dados em DW (Data Warehouse).
A sintaxe utilizada nos exemplos de
Trigger do SQL Server, mas a lgica
da utilizao de Trigger para armazenar informaes sobre alteraes nas
tabelas pode ser utilizada em outros
bancos de dados.
Nesse artigo vamos apresentar dois
exemplos, o primeiro utilizando trigger,
e o segundo, o recurso CDC.

Nesse artigo ser demonstrado o recurso Change


Data Capture (CDC) presente no MS SQL Server
2008 e como utilizar Trigger para registrar as alteraes ocorridas nas tabelas. Abordaremos a melhor forma de utiliz-los em auditorias no banco
de dados.

Para que serve?


Para identificar as alteraes ocorridas nas tabelas,
fornecendo condies de comparao e recuperao de dados que foram excludos e/ou alterados.
Possibilita identificar tambm a incluso de novos
registros nas tabelas.

Em que situao o tema til?


Quando se deseja armazenar histricos das
alteraes ocorridas nos dados das tabelas.
Esse recurso permite o registro das atividades
ocorridas nas tabelas das bases de dados, fornecendo informaes importantes para uma
auditoria.

Exemplo usando Trigger


O SQL Server tem trs tipos de trigger:
DML, DDL e de Logon. Utilizaremos
as triggers DML, que sero disparadas

SQL Magazine - Usando CDC e Trigger em Auditorias no SQL Server 2008


25/02/2010 14:31:04

sql server

quando ocorrer a execuo de instrues DML (insert, delete


ou update) nas tabelas em que elas estiverem vinculadas.
Em nosso exemplo criaremos uma base de dados chamada
Teste, uma tabela na qual conter os dados de exemplo, que
chamaremos de Cliente, uma tabela para registrar as alteraes,
que chamaremos de Cliente_Log, e trs triggers que sero
responsveis por atualizar a tabela Cliente_Log sempre que
ocorrer alteraes nos dados da tabela Cliente (Figura 1).

Cliente

tr_cliente_update
tr_cliente_delete
tr_cliente_insert

Cliente_Log

Figura 1. Exemplo usando Trigger

Para criar o ambiente necessrio para o exemplo, abra o


Microsoft SQL Server Management Studio (SSMS) e efetue o
logon no SQL Server. Feito isso, teremos uma tela semelhante
a da Figura 2.

Figura 2. Tela do SSMS

Criaremos inicialmente uma base de dados chamada


Teste e duas tabelas chamadas Cliente e Cliente_Log
(Listagem 1).
A tabela Cliente a nossa tabela principal, Cliente_Log
uma tabela que contm todos os campos da tabela principal,
mais quatro campos adicionados no final. Esses campos sero
utilizados para guardar informaes sobre as operaes ocorridas na tabela principal, so eles:
Log Usurio contm o usurio que estava conectado na
instncia do SQL Server quando ocorreu a operao;
Log Data data e hora que ocorreu a operao;
Log Operao tipo da operao que ocorreu, podendo ser
Insert, Delete ou Update;
Log ID identificador sequencial.
Aps a criao das tabelas, vamos criar trs triggers, uma
para cada operao (insert, update e delete), apresentadas na
Listagem 2.

Listagem 1. Cdigo de criao da base de dados e das tabelas.


use master
go
-- Criar a base de dados
create database Teste
go
use Teste
go
-- Criar a tabela Cliente
CREATE TABLE dbo.Cliente
(
ID_Cliente int NOT NULL IDENTITY (1, 1),

Nome varchar(50) NOT NULL,

Idade int NOT NULL

)
GO
ALTER TABLE
dbo.Cliente -- Adiciona ID_Cliente como chave
primaria
ADD CONSTRAINT PK_Cliente_1 PRIMARY KEY CLUSTERED (ID_Cliente)

GO

-- Criar a tabela Cliente_Log
CREATE TABLE dbo.Cliente_Log
(
ID_Cliente int NOT NULL,

Nome varchar(50) NOT NULL,

Idade int NOT NULL,

Log_Usuario varchar(30) NOT NULL,

Log_Data datetime NOT NULL,

Log_Operacao char(1) NOT NULL,

Log_ID int NOT NULL IDENTITY (1, 1)

)
GO
ALTER TABLE
dbo.Cliente_Log -- Adiciona LOG_ID como chave
primaria
ADD CONSTRAINT PK_Cliente_Log_1 PRIMARY KEY CLUSTERED (LOG_ID)

GO

Observando o cdigo da Listagem 2, notamos que as diferenas


entre cada SP mnima, so as instrues indicando quando
sero disparadas (after insert, after delete ou after update), a letra indicando qual o tipo de operao (I, U ou D), e a origem das
informaes (tabela inserted ou deleted). Como j informamos,
elas sero disparadas quando operaes de insert, update e delete
so efetuadas na tabela Cliente.
A instruo after delete presente na trigger tr_d_Cliente_Log
indica que essa trigger executar a instruo SQL quando uma
operao de delete for executada na tabela Cliente. Dessa mesma
forma, as outras triggers sero disparadas quando as demais
operaes forem executadas, de acordo com a instruo presente
em cada uma (after insert e after update).
Listagem 2. Cdigo de criao de trigger.
USE [Teste]
GO
CREATE trigger [dbo].[tr_d_Cliente_Log] ON [dbo].[Cliente]
after delete
as
insert Cliente_Log

select *,system_user,getdate(),D from deleted

GO
CREATE trigger [dbo].[tr_i_Cliente_Log] ON [dbo].[Cliente]
after insert
as
insert Cliente_Log

select *,system_user,getdate(),I from inserted

GO
CREATE trigger [dbo].[tr_u_Cliente_Log] ON [dbo].[Cliente]
after update
as
insert Cliente_Log

select *,system_user,getdate(),U from deleted

GO

Edio 72 - SQL Magazine


SQL73.indb 55

55

25/02/2010 14:31:04

As instrues SQL presentes nas triggers, quando executadas,


inserem registros na tabela Cliente_Log fazendo um Select na
tabela inserted ou deleted. Essas tabelas so utilizadas internamente pelo SQL Server para fazer o controle das operaes DML,
e podem ser referenciadas nas triggers. A tabela inserted contm
os registros que esto sendo inseridos na tabela, enquanto deleted
armazena os registros que esto sendo apagados.
Analisando a instruo Select da trigger tr_d_Cliente_Log, verificamos que est sendo feita uma consulta nas informaes que
estavam na tabela Cliente antes de serem apagadas, utilizando
a tabela interna deleted. Posteriormente executada a instruo
Insert que insere na tabela Cliente_Log as informaes retornadas da consulta da tabela interna deleted.
As instrues presentes nas triggers fazem uso das funes
getdate() para obter a data e hora atual, e da system_user para
obter o usurio que est conectado na instncia do SQL Server.
Para testar a trigger de insert (tr_i_Cliente_Log), vamos inserir trs registros na tabela Cliente, conforme a Listagem 3.
A Figura 3 mostra os registros nas tabelas aps a insero
dos trs registros na tabela Cliente. Nota-se na tabela Cliente_Log que os campos Log_Usuario, Log_Data e Log_Operao foram preenchidos pela trigger. Esses campos contm
informaes importantes sobre o que ocorreu na tabela,
podendo contribuir significativamente em um processo de
auditoria no banco de dados.

Figura 3. Contedo das tabelas aps a insero de trs registros


Listagem 3. Inserir trs registros na tabela Cliente.
USE Teste
go
-- Mostra o conteudo das tabelas antes do Insert
select
* from Cliente
select
* from Cliente_Log
-- Insere 3 registros
insert
Cliente (Nome, Idade) values (Tulio,35)
insert
Cliente (Nome, Idade) values (Joo,25)
insert
Cliente (Nome, Idade) values (Maria,15)
-- Mostra o conteudo das tabelas depois do Insert
select
* from Cliente
select
* from Cliente_Log

Para exemplificar as operaes de excluso e alterao de


registros, execute o cdigo da Listagem 4.
A Figura 4 mostra os registros nas tabelas aps a excluso e
alterao dos registros na tabela Cliente.
Observando o campo Log_Operao da tabela Cliente_Log,
temos a informao do tipo de operao que ocorreu quando foi

56
SQL73.indb 56

Listagem 4 . Excluir e alterar registros na tabela Cliente


USE Teste
go
-- Mostra o conteudo das tabelas antes do Delete e Update
select
* from Cliente
select
* from Cliente_Log
-- Excluie um registro
delete
Cliente where ID_Cliente = 2
-- Altera um registro
update
Cliente set Nome = Fulana where ID_Cliente = 3
-- Mostra o conteudo das tabelas depois do Delete e Update
select
* from Cliente
select
* from Cliente_Log

Figura 4. Contedo das tabelas aps a excluso e alterao de registros

inserido o registro, sendo I para insero, D para excluso


e U para atualizao.
Note que a tabela Cliente_Log contm todos os registros
que estavam antes das operaes de excluso e atualizao na
tabela Cliente. Por exemplo, na tabela Cliente temos o nome
Fulana, se olharmos na tabela Cliente_Log, consta o nome
Maria, ou seja, o registro antes da operao de atualizao.
Vale ressaltar que quando utilizamos triggers para
inserir informaes em tabelas estamos utilizando mais
recursos do servidor, isto , uma operao que iria inserir
um registro na base de dados, nesse caso, passa a inserir
dois registros. Por isso, importante fazer uma anlise de
quais tabelas so realmente importantes e necessitam de
uma tabela de Log.

Exemplo usando o CDC


O Change Data Capture (CDC) utiliza os log (arquivos .ldf)
para identificar as alteraes ocorridas nas tabelas. Quando
uma operao DML executada, essas informaes so salvas primeiramente nos arquivos de log e posteriormente na
tabela de origem.
Atravs de um processo de captura, as informaes sobre as alteraes ocorridas na tabela que esto nos arquivos de log so lidas
e salvas tambm em tabelas de histrico do CDC (Figura 5).
Em nosso exemplo sobre o CDC, iremos criar uma base
chamada TesteCDC, adicionar uma tabela chamada Fornecedor, habilitar a base para utilizao do CDC e incluir a tabela
Fornecedor no processo de CDC.
Para criar o ambiente necessrio para o exemplo, abra o SQL
Server Management Studio e efetue o logon no SQL Server.
Feito isso, teremos uma tela semelhante a da Figura 2.
Agora criaremos uma base chamada TesteCDC e a tabela
Fornecedor, como apresenta o cdigo da Listagem 5.

SQL Magazine - Usando CDC e Trigger em Auditorias no SQL Server 2008


25/02/2010 14:31:05

sql server

Figura 6. Resultado da verificao se o CDC est habilitado


Listagem 7. Verificao se o CDC esta habilitado.
use master
go
select name,

i
s_cdc_enabled
from
sys.databases
where
is_cdc_enabled = 1

Figura 5. Funcionamento do CDC


Listagem 5. Cdigo da criao da base e tabela.
use master
go
-- Criar a base de dados
create database TesteCDC
go
use TesteCDC
go
-- Criar a tabela Fornecedor
CREATE TABLE dbo.Fornecedor
(
ID_Fornecedor int NOT NULL IDENTITY (1, 1),

Nome varchar(50) NOT NULL,

Telefone int NOT NULL

)
GO
ALTER TABLE
dbo.Fornecedor -- Adiciona chave primaria
ADD CONSTRAINT PK_Fornecedor_1 PRIMARY KEY CLUSTERED (ID_
Fornecedor)
GO

Aps a criao da base de dados e da tabela, usaremos a


stored procedure sp_cdc_enable_db para habilitar a base de
dados para utilizar o CDC, e a SP sp_cdc_enable_table para
incluir a tabela no processo CDC (Listagem 6).
Para verificar quais bases de dados esto com o recurso
CDC habilitado, podemos fazer uma consulta na tabela sys.
Database, buscando pelo campo is_cdc_enabled igual a 1.
Para verificar quais tabelas esto includas no CDC, devemos consultar a tabela sys.Tables, buscando pelo campo
is_tracked_by_cdc igual a 1. A Listagem 7 mostra as duas
consultas, tendo o resultado mostrado na Figura 6.
Listagem 6. Cdigo para habilitar o CDC e incluir a tabela.
use TesteCDC
go
-- Habilitando a base de dados
exec sys.sp_cdc_enable_db
go
-- Adicionando a tabela
exec sp_cdc_enable_table
@
source_schema = dbo,
@
source_name = Fornecedor,
@
role_name = CDC_Role,
@
supports_net_changes = 1
Go

-- Tabela
use TesteCDC
go
select
name,

i
s_tracked_by_cdc
from
sys.tables
where
is_tracked_by_cdc = 1

Quando executamos a SP sp_cdc_enable_db para habilitar


a base de dados para utilizao do CDC, so criados os seguintes objetos no SQL Server: um Schema chamado cdc, um
usurio chamado cdc e cinco tabelas de sistemas que contero
informaes sobre o CDC (Figura 7).
Quando executamos a SP sp_cdc_enable_table para incluir
a tabela no CDC, criada uma nova tabela de sistema com o
nome da tabela de origem contendo no final a identificao
_CT. Essa tabela contm todos os campos da tabela de origem
mais cinco campos de controle, conforme a Figura 8. Em
nosso exemplo tambm ser criada, se no existir, uma Role
chamada CDC_Role, que ser responsvel por permitir o acesso
s informaes nas tabelas _CT quando o usurio no tiver
permisso de db_owner.
Ao executar a SP sp_cdc_enable_table pela primeira vez,
sero criados dois JOBs (Figura 9). No nosso exemplo, o
primeiro chamado cdc_dbo_TesteCDC_capture, o qual
ser iniciado junto com a instncia do SQL Server e ser
responsvel pela leitura das informaes sobre alteraes
que foram registradas nos arquivos de log. As alteraes
identificadas sero salvas na tabela de sistema que foi
criada com a identificao _CT. O segundo JOB criado
o cdc_TesteCDC_cleanup, responsvel por apagar as informaes antigas das tabelas _CT. Por default, esse JOB
executado diariamente s 2:00 hs, e a cada execuo so
apagados os registros das tabelas _CT que tenham mais de
72 horas (antigos). Caso seja necessrio manter por mais
tempo as informaes nas tabelas _CT, podemos alterar
o tempo de reteno utilizando a SP sp_cdc_change_job.
O tempo mximo permitido de 100 anos, o valor para o
parmetro da SP chamado retention tem que ser informado
em minutos. A Listagem 8 mostra a alterao para 100 anos.
Uma boa prtica manter um perodo pequeno (um ms,

Edio 72 - SQL Magazine


SQL73.indb 57

57

25/02/2010 14:31:05

dependendo da quantidade de transaes) e criar uma rotina


para descarte dos registros antigos, salvando-os em outro
SQL Server ou em arquivos texto (.txt), para o caso de ser
necessria a consulta dessas informaes no futuro.
Aps habilitar a base de dados para utilizar o CDC e incluir
a tabela de exemplo Fornecedor, iremos inserir trs registros
nesta tabela e depois selecionar os registros nas tabelas Fornecedor e cdc.dbo_Fornecedor_TC para mostrar o que ocorreu
(veja o cdigo na Listagem 9).
A Figura 10 mostra o resultado obtido aps a execuo do
cdigo da Listagem 9.

Figura 9. JOB criado quando includo a tabela


Listagem 8. Alterando o tempo de reteno
use TesteCDC
go
exec sp_cdc_change_job @job_type=cleanup, @retention=52494800
go

Listagem 9. Operaes na tabela de fornecedor.


USE TesteCDC
go
-- Mostra o conteudo das tabelas antes do Insert
select
* from Fornecedor
select
* from cdc.dbo_Fornecedor_CT
-- Insere 3 registros
insert
Fornecedor(Nome, Telefone) values (Tulio,1111)
insert
Fornecedor (Nome, Telefone) values (Joo,2222)
insert
Fornecedor (Nome, Telefone) values (Maria,3333)
-- Mostra o conteudo das tabelas depois do Insert
-- Esperar 5 segundos antes de executar essa parte
select
* from Fornecedor
select
* from cdc.dbo_Fornecedor_CT

Figura 7. Objetos criados quando habilitado o CDC

Para realizar consultas nas tabelas de sistemas terminadas em _CT podemos tambm utilizar a funo (FN) cdc.
fn_get_net_changes_dbo_Fornecedor. Essa funo criada
no momento em que adicionamos a tabela Fornecedor no CDC.
A Listagem 10 demonstra a utilizao da FN.
Listagem 10. Usando a FN cdc.fn_get_net_changes_dbo_Fornecedor.
use TesteCDC
go
declare @from_lsn binary(10),
@to_lsn binary(10)


set @from_lsn = sys.fn_cdc_get_min_lsn(dbo_Fornecedor)
-- Menor data
set @to_lsn
= sys.fn_cdc_get_max_lsn() -- Maior data
select * from
cdc.fn_cdc_get_net_changes_dbo_Fornecedor(@from_lsn, @to_lsn, all);

Figura 8. Tabela criada pela SP sp_cdc_enable_table

58
SQL73.indb 58

Se observarmos a Figura 10, veremos que o primeiro resultado (tabela Fornecedor) retornou os registros que foram
inseridos. O segundo resultado retornou o mesmo contedo
da tabela Fornecedor mais algumas informaes adicionais.
Dentre estas informaes, as mais importantes so __$start_
lsn, que contm a data e a hora que a operao foi executada,
e __ $operation, que contm o tipo de operao.

SQL Magazine - Usando CDC e Trigger em Auditorias no SQL Server 2008


25/02/2010 14:31:05

sql server

Para visualizar a data que est no campo __ $start_lsn podemos fazer uso da funo sys.fn_cdc_map_lsn_to_time.
A Tabela 1 mostra o significado dos cdigos do campo
__$operation.
Cdigo

Descrio

Excluso

Insero

Antes da alterao

Aps a alterao

Tabela 1. Cdigos do campo __$operation

Para entender melhor o exemplo, vamos alterar um registro


e excluir outro (veja a Listagem 11). Na Figura 11 apresentamos os resultados aps a alterao e excluso dos registros. O
primeiro resultado mostra a tabela Fornecedor, que contm
agora dois registros. Para saber o que ocorreu nessa tabela,
recorremos tabela cdc.dbo_Fornecedor_CT.
Observando cdc.dbo_Fornecedor_CT, temos nos trs primeiros registros a informao de incluso, pois no campo
__ $operation est presente o cdigo 2. O contedo inserido
o que consta nos ltimos campos desses registros (ID_Fornecedor, Nome e Telefone).
O quarto e quinto registro da tabela cdc.dbo_Fornecedor_CT contm informaes sobre as alteraes ocorridas

na tabela Fornecedor. O campo __ $operation com cdigo 3


informa que o registro contm os dados que existiam na
tabela Fornecedor antes da alterao, e no quinto registro
(__$operation = 4) os dados aps a alterao. O CDC no registra o usurio que executou a instruo DML na tabela.
A Listagem 12 mostra como fazer para adicionar o campo
Estado na tabela Fornecedor.

Listagem 11. Alterao e excluso de registros.


USE TesteCDC
go
-- Alteracao
update dbo.Fornecedor set Nome = Tulio Rosa where ID_
Fornecedor = 1
-- Exclusao
delete dbo.Fornecedor where ID_Fornecedor = 2
-- Mostra o conteudo das tabelas depois da alteracao e exclusao
-- Esperar 5 segundos antes de executar essa parte
select
* from Fornecedor
select
* from cdc.dbo_Fornecedor_CT

Listagem 12 . Adicionando o campo Estado.


use TesteCDC
go
-- Adicionando o campo estado
alter table dbo.Fornecedor add
Estado char(2)

GO

Figura 10. Contedo das tabelas Fornecedor e dbo_Fornecedor_CT

Figura 11. Resultado aps a alterao e excluso dos registros

Edio 72 - SQL Magazine


SQL73.indb 59

59

25/02/2010 14:31:06

Como foi habilitado o CDC na tabela Fornecedor, ao adicionar


um novo campo as informaes referentes a alteraes (instrues DDL) so armazenadas na tabela cdc.ddl_history. A
Listagem 13 mostra como efetuar a consulta nessa tabela, e o
resultado pode ser conferido na Figura 12.
Listagem 13 . Consulta nas tabelas aps adicionar o novo campo.
use TesteCDC
go
select *
select *

from Fornecedor
from cdc.dbo_Fornecedor_CT

select



from

OBJECT_NAME(source_object_id) as Tabela,
O
BJECT_NAME(OBJECT_ID) as Tabela_CT,
d
dl_command as DDL,
d
dl_time as Data
cdc.ddl_history

um registro e alter-lo, de acordo com a Listagem 15. O novo


resultado pode ser conferido na Figura 13.
Listagem 14 . Retira e adiciona novamente a tabela Fornecedor.
use TesteCDC
go
-- Retirando a tabela
exec sp_cdc_disable_table
@
source_schema = dbo,
@
source_name = Fornecedor,
@
capture_instance = all
go
-- Adicionando a tabela
exec sp_cdc_enable_table
@
source_schema = dbo,
@
source_name = Fornecedor,
@
role_name = CDC_Role,
@
supports_net_changes = 1
go

Listagem 15. Efetuando alteraes no novo campo.

Como pode ser verificado na Figura 12, o novo campo foi


adicionado na tabela Fornecedor, mas no foi adicionado na
tabela Fornecedor_CT. Para resolver esse problema a forma mais
simples retirar e adicionar novamente a tabela Fornecedor
no CDC, conforme a Listagem 14. importante observar que
quando retiramos uma tabela do CDC, a tabela corespondente
_CT apagada, perdendo todo o seu contedo. Ento, se existe
a inteno de manter os dados das tabelas _CT, os registros
dessas tabelas precisam ser copiados para outra tabela antes
da operao de retirar a tabela do CDC.
Para verificar a utilizao do novo campo, iremos inserir

use TesteCDC
go
-- Inserindo
Insert Fornecedor(Nome, Telefone,Estado) values
(Fabiola,5555,GO)
-- Alteracao
update dbo.Fornecedor set Estado = DF where ID_Fornecedor = 3

Para melhorar a visualizao do histrico (tabelas _CT), podemos criar uma stored procedure para formatar o resultado
destas tabelas. A Listagem 16 mostra o cdigo de criao da
SP. Ela recebe como parmetros o nome da tabela, a data inicial

Figura 12. Resultado das consultas aps adicionar o novo campo

Figura 13. Resultado da alterao do novo campo

60
SQL73.indb 60

SQL Magazine - Usando CDC e Trigger em Auditorias no SQL Server 2008


25/02/2010 14:31:06

sql server

Figura 14. Resultado da SP cdc.s_historico

create proc cdc.s_historico @tabela varchar(100), @data_inicial


varchar(23), @data_final varchar(23)
as
exec
(
select s
ys.fn_cdc_map_lsn_to_time(__$start_lsn) as Data,

case __$operation


w
hen 1 then D

w
hen 2 then I

w
hen 3 then UA

w
hen 4 then UD

e
nd as Operacao,
*
into #temp
from c
dc. + @tabela +
where s
ys.fn_cdc_map_lsn_to_time(__$start_lsn)

between + @data_inicial + and + @data_final +

alter table #temp drop column __$start_lsn


alter table #temp drop column __$operation
alter table #temp drop column __$update_mask
alter table #temp drop column __$seqval
alter table #temp drop column __$end_lsn
select *
from #
temp
order
by Data
)

Listagem 17. Utilizao da SP cdc.s_historico.


use TesteCDC
go
exec cdc.s_historico dbo_Fornecedor_CT,2009-11-01,2009-11-30
go

A Tabela 2 mostra o significado dos cdigos do campo Operao, da Figura 14.


Operao

Descrio

Inserido

Apagado

UA

Dados antes da alterao

UD

Dados aps a alterao

Tabela 2. Cdigos do campo Operao

Consideraes sobre Trigger e CDC

Demonstramos nesse artigo duas formas de armazenar informaes sobre as operaes (insert, update e delete) que ocorrem
nas tabelas, atravs de Triggers e CDC. Podemos utilizar essas
informaes para entender o que ocorreu na tabela e quando,
o que muito til em um processo de auditoria.
Imagine o seguinte cenrio: um funcionrio da empresa que
tenha acesso ao sistema de contas a pagar e receber altera de
forma fraudulenta o valor que a empresa tem a receber de um
determinado cliente. Atravs da utilizao dos recursos demonstrados nesse artigo possvel identificar quando foi feita
a alterao, por quem e ainda teremos condies de corrigir o
valor alterado, voltando ao valor inicial.
Para concluir, vale destacar que a utilizao dos recursos de
triggers ou do CDC aumentaro o consumo de recursos do
servidor onde est instalado a instncia do SQL Server. Por isso,
tenha cuidado ao utilizar estes recursos e evite que o desempenho do banco seja prejudicado.
Links
SQL Server Developer Center
http://msdn.microsoft.com/en-us/library/cc645937.aspx
http://msdn.microsoft.com/en-us/library/ms189799.aspx

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/sqlmagazine/feedback

Edio 72 - SQL Magazine


SQL73.indb 61

Feedback
eu
sobre e
s

Como podemos observar, tanto a utilizao dos recursos de


Triggers como CDC inserem registros em tabelas na base de
dados, e com isso temos o aumento de utilizao de recursos
do servidor onde est instalado a instncia do SQL Server.
A utilizao do CDC mais vantajosa que as Triggers devido
ao fato das atualizaes serem buscadas dos arquivos de log,

Concluso

D
s

Listagem 16. Criao da SP para retornar o resultado formatado.

de forma assncrona, enquanto as Triggers fazem a incluso


dos registros em todas as tabelas de forma sncrona.
Outra vantagem do CDC que podemos par-lo em momentos crticos, isto , onde esteja ocorrendo um grande numero de transaes (atividade intensa no banco de dados), e
voltar a atualizar as tabelas _CT quando a carga no servidor
estiver mais baixa, sem perda de informaes.
Para suspender temporariamente o CDC, utilizamos a SP sys.sp_
cdc_stop_job, e para voltar a utilizar o CDC, utilizamos a SP sys.
cdc_start_job. importante saber que o arquivo de log aumentar
enquanto o servio estiver suspenso, uma vez que as informaes
sobre as alteraes nos dados das tabelas so salvas nos arquivos
de log, e ficam disponveis at o CDC fazer a leitura. Aps voltar
a utilizar o CDC as informaes que estavam nos arquivos de log
so liberadas para serem descartadas ou includas em backup.

edio
ta

e a data final. Estas datas so referentes ao perodo em que se


deseja visualizar as alteraes. A Listagem 17 mostra a sua
utilizao. Observando o resultado na Figura 14, temos a data
em que ocorreu a operao, o tipo da operao e os campos do
registro da tabela de origem.

61

25/02/2010 14:31:06

Seo Projeto/Modelagem

Seo Banco de Dados/Persistncia

Nesta seo voc encontra artigos sobre


banco de dados, SQL ou persistncia

Desafio SQL

De que se trata o artigo?

E a empresa ItsMyBusiness continua crescendo. E seu

Desenvolvimento de solues para problemas cotidianos enfrentados por DBAs e desenvolvedores de


aplicaes para banco dados.

sistema de vendas on-line tambm est crescendo e em


larga escala.
Novos processos e novas implementaes tem sido
necessrias para acompanhar a evoluo dos negcios e
resolver os problemas que no foram previstos no momento
do projeto.
E justamente neste momento surge a velha discusso de
onde a regra de negcio deve estar: camada de aplicao,
camada intermediria ou diretamente no banco de dados.
Wagner Crivelin, como bom DBA, partidrio de manter
a regra de negcios diretamente no banco de dados e, com
esta filosofia, vem nos brindar com mais um desafio.
E caso voc tenha alguma dvida, sugesto de tema ou at
mesmo um novo desafio, envie um e-mail para mim.
Aproveite.
Ricardo Rezende - Editor Tcnico
ricardo@sqlmagazine.com.br

Wagner Crivelini
wcrivelini@gmail.com

Atua a mais de 15 anos na rea TI, particularmente com Business Intelligence. Engenheiro formado pela UNICAMP, trabalha
na IBM na unidade de IBM Global Account.
Profissional com certificao em DB2 (IBM
Certified Solution Designer DB2 Business
Intelligence). Colunista convidado do portal
internacional www.SQLServerCentral.com .
Atualmente ocupa a posio de DBA DB2.

62
SQL73.indb 62

Para que serve?

voltamos para acompanhar mais


um captulo da histria da empresa fictcia ItsMyBusiness (leia
nota DevMan 1).
A empresa est realizando um projeto para melhorar o controle sobre os
pedidos recebidos, j definiu o modelo
de dados e o fluxo de operao, que so
exibidos nas Figuras 1 e 2.
A Tabela 1 mostra os cdigos de status
que consideramos neste fluxo e uma
breve descrio de cada um.
O script para criao desta base de
dados est disponvel no portal da
SQL Magazine. Este script adota um
padro SQL, de tal modo que ele roda,
com pequenas alteraes, em SQL
SERVER, DB2, ORACLE, FIREBIRD e
POSTGRES. As alteraes necessrias
para cada SGBD so apresentadas como
comentrios.

Fornecer conceitos de utilizao de funcionalidades


do padro SQL ANSI na resoluo de problemas enfrentados no dia-a-dia na recuperao de informaes do banco de dados.

Em que situao o tema til?


Criao de procedimentos armazenados, gatilhos e agendamentos (ou stored procedures,
triggers e jobs).

Feitas as preliminares, agora falta


trabalhar numa outra parte do projeto:
como sincronizar os eventos ocorridos
com as mudanas de status do pedido.
Sempre existiu e sempre existir o
debate sobre onde que esta lgica de
negcios deve ser implementada. Cada
tribo defende o seu ponto de vista: uns
defendem que a lgica deve ficar na
aplicao, outros dizem que ela deve
residir dentro do prprio banco de

SQL Magazine - Desafio SQL


25/02/2010 14:31:07

D ESAFIO S QL

dados e existem tambm aqueles que gostam de tratar tudo


atravs de servios intermedirios (web, windows, etc).
claro que eu (e provavelmente voc tambm) fao
parte de uma destas tribos e tambm vou adotar um dos
partidos.
O desafio de hoje implementar toda lgica de atualizao
dos status do pedido usando apenas recursos do banco de
dados, tomando por base as informaes apresentadas:
no diagrama do modelo do banco (Figura 1)
no diagrama do fluxo de trabalho (Figura 2)
e na lista de cdigos de status considerados (Tabela 1).
Ou seja, podemos escolher usar procedimentos armazenados,
funes e gatilhos, conforme a necessidade. Boa sorte.

codPedidoStatus

Descrio do status

pedido registrado no site

carto de crdito validado

pedido aceito

item do pedido disponvel em estoque

nota fiscal emitida

remessa do pedido para transportadora

pedido entregue

pedido finalizado

102

carto de crdito rejeitado

103

pedido recusado

Tabela 1. Cdigos das aes relacionadas a um pedido

Figura 1. Modelo de dados simplificado da empresa ItsMyBusiness

Figura 2. Fluxo das operaes relacionadas a um item de pedido

Edio 72 - SQL Magazine


SQL73.indb 63

63

25/02/2010 14:31:08

Resposta do desafio
Vamos agora fazer um estudo detalhado dos eventos e aes
a serem executadas para todo o fluxo de operaes de um
pedido.
Esta tarefa longa para cobrirmos num artigo, j que vamos criar vrios objetos diferentes e eu vou mostrar aqui os
conceitos que vamos usar em cada um deles. A sintaxe das
linguagens usadas em cada SGBD varia consideravelmente,
mas os conceitos que vou mostrar so aplicveis a todos os
SGBDs.
Por isso, para simplificar, vou me limitar a mostrar a criao
dos objetos usando apenas uma linguagem, T-SQL, que usada
pelo SQL Server. Fica a seu critrio transcrever esta lgica para
o seu SGBD.
A primeira tarefa que temos analisar as Figuras 1 e 2 e traduzir os eventos de mudana de status em aes no banco de
dados. De forma geral, todos os eventos exibidos na Figura 2
(do evento 1 ao 8, sem exceo) se traduzem numa nica ao
no banco de dados: a insero de um novo registro na tabela
dbo.tblPedidoHistorico, identificando um novo status para um
dado item do pedido.
A Figura 3 mostra em detalhes a estrutura da tabela de
histrico.

Column Name

Data Type

codPedido

int

codProduto

int

codPedidoStatus

int

DataEvento

datetime

Observacao

varchar(50)

Allow Nulls

Figura 3. Estrutura da tabela dbo.tblPedidoHistorico

Para simplificar, deixaremos o campo OBSERVACAO inalterado, aproveitando que ele aceita valores nulos. Ento, nossa ao ser sempre uma declarao de insero do tipo
INSERT INTO dbo.tblPedidoHistorico
VALUES(PedidoAtual, ProdutoAtual, StatusNovo, DataAtual,
NULL)

Esta declarao SQL ser usada para todas as mudanas de


status do pedido. Por esta razo, uma boa idia transformla num procedimento armazenado. Este procedimento pode
ser invocado por outros objetos do banco de dados, assim
como por aplicaes e/ou servios externos.
Assim, conforme combinamos, mostro aqui o script para
criao deste procedimento no SQL Server (Listagem 1).
Listagem 1. Criao do procedimento armazenado spPedidoHistoricoINSERT
1
2
3
4
5

64
SQL73.indb 64

Ns acompanhamos nesta coluna o dia-a-dia da empresa fictcia ItsMyBusiness,


que uma empresa de varejo que fez recentemente o seu site de e-commerce.
E o site est vendendo muito! O sucesso tanto que um projetinho despretensioso (e mal feito) de criar um mecanismo para vendas pela internet est
comeando a fazer gua... E a empresa precisa consertar as coisas antes que os
problemas fiquem mais srios.
Uma srie de correes e melhorias tem sido feitas no site da ItsMyBusiness, especialmente na base de dados, que o que nos interessa.
Recentemente foi lanado um projeto para a empresa ter um controle melhor
sobre o ciclo de vendas de cada pedido que recebe no seu site. Trata-se de um novo
processo de acompanhamento do status do pedido, que vai desde o registro do pedido at o momento em que se entregam os produtos ao cliente.

Precisamos agora identificar quais eventos disparam esta


ao e tambm quais valores usaremos para cada campo a
ser inserido.
Vamos analisar o fluxo de operaes (Figura 2) e estabelecer
os eventos passo a passo, ou seja, eventos relacionados com
cada cdigo de status do pedido.

Status 1: pedido registrado no site

tblPedidoHistorico

Nota do DevMan 1

CREATE PROCEDURE dbo.spPedidoHistoricoINSERT


(@Pedido INT, @Produto INT, @Status INT)
AS
INSERT INTO dbo.tblPedidoHistorico
V
ALUES(@Pedido, @Produto, @Status, GETDATE() , NULL) ;

Este evento ocorre logo que se registra o pedido no banco de


dados da ItsMyBusiness.
Porm no basta termos o nmero do pedido. Para fins de
definio de status, precisamos conhecer o nmero do pedido
e o cdigo do produto em questo.
Portanto, o evento que devemos considerar para fins de alterao de status de pedido a insero na tabela de detalhe dos
pedidos, dbo.tblPedidoDetalhe. Vamos usar um gatilho do tipo
AFTER INSERT, ou seja, o gatilho disparado assim que um
novo registro for inserido na tabela de detalhes do pedido.
Vamos recuperar o cdigo do pedido e o cdigo do produto
em questo buscando as informaes na tabela virtual INSERTED (veja nota DevMan 2).
Para completar, deveremos informar qual o cdigo do status
que vamos considerar. Isso simples: basta olhar a Tabela 1 e
veremos que este evento est associado ao cdigo 1.
Com todas as informaes em mos, finalmente inserimos
um novo registro, agora na tabela de histrico do pedido (dbo.
tblPedidoHistorico). A Listagem 2 mostra o script deste gatilho.
Listagem 2. Gatilho dbo.trgPedDet_ins
1 CREATE TRIGGER dbo.trgPedDet_ins
2 ON dbo.tblPedidoDetalhe
3 AFTER INSERT
4 AS
5 BEGIN
6 --usaremos valores da tabela virtual INSERTED
7 DECLARE @PedidoNovo INT
8 DECLARE @ProdutoNovo INT
9
10 SELECT @PedidoNovo = codPedido FROM INSERTED
11 SELECT @ProdutoNovo = codProduto FROM INSERTED
12 -- codigo status 1 = pedido aceito
13 EXEC dbo.spPedidoHistoricoINSERT @PedidoNovo,@ProdutoNovo,1
14 END ;

SQL Magazine - Desafio SQL


25/02/2010 14:31:08

D ESAFIO S QL

Status 2 e/ou 102: carto de crdito validado/rejeitado


A validao do carto de crdito do cliente feita mediante
um web service. Sendo assim, quem gerencia esta etapa a
aplicao.
A ao executada na aplicao ser checar a resposta do web
service e invocar o procedimento armazenado spPedidoHistoricoINSERT, apresentado na Listagem 1. O cuidado principal
neste passo que o cdigo de status ser igual a 2 se o carto for
validado, e 102 se o carto for rejeitado.

Status 3 e/ou 103: pedido aceito/recusado


Na realidade, estes dois passos so simblicos, porque o nosso
fluxo de operao (Figura 2) prev que o pedido passa automaticamente do status 2 para 3 (assim como do status 102 para 103).
A melhor maneira de implementar isso criando um gatilho
na prpria tabela de histrico do pedido. No importa que este
gatilho cause a insero de um novo registro na prpria tabela.
Contanto que a lgica deste gatilho seja bem implementada, no
teremos problema com isso.
Este gatilho funcionar de forma muito parecida com o gatilho
dbo.trgPedDet_ins (Listagem 2), apenas acrescentando os testes
condicionais na sua lgica para sabermos se caso de carto
validado ou rejeitado, como vemos na Listagem 3.

Status 4: item do pedido disponvel em estoque


O prximo passo verificar se o produto est disponvel em estoque. Aqui cabe um comentrio importante. Observe na Figura 2
que o fluxo no prev a hiptese de existir uma quantidade
insuficiente do produto no estoque. Ou remetemos a quantidade total do produto requerida no pedido, ou no enviamos
nada. Isto de fato uma limitao do modelo, mas agora no
o momento de discutirmos isso. Para todos os efeitos prticos,
o arquiteto da aplicao j fez um bom trabalho criando um
modelo de dados que permite que se fature separadamente os
itens de um pedido.
Listagem 3. Gatilho dbo.trgPedHist_ins
1 CREATE TRIGGER dbo.trgPedHist_ins
2 ON dbo.tblPedidoHistorico
3 AFTER INSERT
4 AS
5 BEGIN
6 --usaremos valores da tabela virtual INSERTED
7 D
ECLARE @PedidoNovo INT
8 DECLARE @ProdutoNovo INT
9
10 SELECT @PedidoNovo = codPedido FROM INSERTED
11 SELECT @ProdutoNovo = codProduto FROM INSERTED
12
13 IF (SELECT codPedidoStatus FROM INSERTED) = 2
14 EXEC dbo.spPedidoHistoricoINSERT @PedidoNovo,@ProdutoNovo,3
15 ELSE
16 BEGIN
17 IF (SELECT codPedidoStatus FROM INSERTED) = 102
18
EXEC dbo.spPedidoHistoricoINSERT
19
@PedidoNovo, @ProdutoNovo , 103
20 END
21 END ;

Feita esta considerao, vamos definir o evento que nos interessa.


Ns temos que monitorar a quantidade do produto disponvel em
estoque e, assim que ela for maior ou igual quantidade solicitada
no pedido, atualizamos o status do pedido para o cdigo 4.

Nota do DevMan 2
Para trabalhar com gatilhos, o SQL Server oferece duas tabelas virtuais: INSERTED
e DELETED. Estas tabelas s podem ser usadas dentro dos gatilhos e elas retornam
as informaes dos registros que so tratados nas declaraes DML. A tabela virtual
INSERTED contm o registro completo que acaba de ser inserido na tabela. A tabela
DELETED tem o registro completo que foi excludo da tabela. E nas declaraes de
UPDATE, por exemplo, teremos as duas tabelas virtuais populadas, DELETED com o
registro antigo e INSERTED com o novo registro.
Cada SGBD usa uma terminologia diferente, mas os conceitos so basicamente os
mesmos. No Oracle e no DB2, por exemplo, temos as tabelas NEW e OLD, que funcionam de maneira muito parecida com o SQL Server.

O mtodo mais simples de fazermos este monitoramento no SQL Server habilitando um job que ser executado
periodicamente.
Digamos que o job seja configurado para rodar a cada 15
minutos. Neste caso, a rotina ser executada, conferindo o
saldo em estoque de todos os itens de pedido que estejam com
status 3. Se houver saldo suficiente, o item do pedido mudar
para o status 4. Do contrrio, este item permanece com o mesmo status at que a rotina seja executada novamente.
Devemos ter um cuidado especial com esta rotina, porque
os pedidos devem ser analisados sequencialmente e em
ordem de cadastramento. Assim vamos garantir que os
pedidos mais antigos sero atendidos primeiro.
Por simplicidade, a rotina que vamos executar ser um
procedimento armazenado. E o sequenciamento dos itens
de pedido ser feito usando-se um cursor.
Dois detalhes importantes:
1. Ns devemos consultar apenas os pedidos que tem o
ltimo status igual a 3. Por isso preciso uma consulta
de sumarizao (GROUP BY) para identificar os pedidos
corretamente.
2. Neste modelo, pedidos so controlados por produto,
mas os saldos so controlados por lote de produto. Ento
ns s teremos o saldo em estoque correto aps fazermos a
sumarizao das quantidades de todos os lotes do mesmo
produto.
Isto nos leva ao script da Listagem 4.
Muito bem, temos a o procedimento a ser agendado.
Quanto ao mtodo de agendamento, existem vrios. No
SQL Server, a maneira mais fcil de fazer isso criando um
job no SQL Server Management Studio, que a ferramenta
grfica de administrao do SGBD.
Um job nada mais do que uma tarefa agendada
que ser controlada por um servio especial do SQL
Server (SQL Agent). Existe uma infinidade de artigos mostrando como criar estes jobs e no vou me
estender nesta questo. A t t ulo de exemplo, reco mendo o artigo da MSDN Como criar um trabalho
(http://msdn.microsoft.com/pt-br/library/ms190268.aspx).

Edio 72 - SQL Magazine


SQL73.indb 65

65

25/02/2010 14:31:09

Listagem 5. Gatilho dbo.trgNFDet_ins


1 CREATE TRIGGER dbo.trgNFDet_ins
2 O
N dbo.tblPedidoDetalhe
3 AFTER INSERT
4 AS
5 BEGIN
6 --usaremos valores da tabela virtual INSERTED
7 DECLARE @PedidoNovo INT
8 DECLARE @ProdutoNovo INT
9
10 SELECT @PedidoNovo = codPedido
11 FROM dbo.tblNotaFiscal
12 WHERE codNotaFiscal = (SELECT codNotaFiscal FROM INSERTED)
13
14 SELECT @ProdutoNovo = codProduto
15 FROM dbo.tblLote
16 W
HERE codLote = (SELECT codLote FROM INSERTED)
17 -- codigo status 5 = nota fiscal emitida
13 EXEC dbo.spPedidoHistoricoINSERT @PedidoNovo,@ProdutoNovo,5
14 END ;

Listagem 6. Atualizao do gatilho dbo.trgPedHist_ins


1 ALTER TRIGGER dbo.trgPedHist_ins
2 ON dbo.tblPedidoHistorico
3 AFTER INSERT
4 AS
5 BEGIN
6 --usaremos valores da tabela virtual INSERTED
7 DECLARE @Pedido INT
8 DECLARE @Produto INT
9
10 SELECT @Pedido = codPedido FROM INSERTED
11 SELECT @Produto = codProduto FROM INSERTED
12
13 IF (SELECT codPedidoStatus FROM INSERTED) = 2
14 EXEC dbo.spPedidoHistoricoINSERT @Pedido, @Produto, 3
15 ELSE
16 BEGIN
17 IF (SELECT codPedidoStatus FROM INSERTED) = 102
18
BEGIN
19
EXEC dbo.spPedidoHistoricoINSERT @Pedido, @Produto, 103
20
EXEC dbo.spPedidoHistoricoINSERT @Pedido, @Produto, 8
21
END
22 ELSE
23
IF (SELECT codPedidoStatus FROM INSERTED) = 7
24
EXEC dbo.spPedidoHistoricoINSERT @Pedido, @Produto, 8
25 END
26 END ;

66
SQL73.indb 66

Aps o servio de faturamento (que no cabe aqui entrarmos em detalhes), as notas fiscais sero emitidas. E ento
ns deveremos passar estes pedidos para o status 5.
Este evento deve acontecer logo aps a insero das
notas na tabela correspondente (tblNotaFiscalDetalhe). Por
isso teremos mais uma vez um gatilho, agora na tabela de
detalhes da nota fiscal. A ao praticamente a mesma da
que mostramos na Listagem 2, com uma exceo.
Ns precisamos ter o pedido correspondente nota fiscal, mas isso registrado na tabela dbo.tblNotaFiscal , que
ser gravada antes da tabela de detalhes. Ento o cdigo
do Pedido no vai existir na tabela virtual INSERTED.
Cabe a ns fazermos uma consulta tabela de notas fiscais
para extrairmos esta informao.
Da mesma forma, a tabela INSERTED s ter o cdigo do
lote faturado e no o cdigo do produto. Mais uma vez,
deveremos fazer uma consulta. Veja a Listagem 5.

Status 6: remessa do pedido para transportadora


O status 6 acontece quando a transportadora retira o
pacote correspondente a cada pedido na expedio da
ItsMyBusiness.
Portanto, neste caso, quem gerencia esta etapa a
aplicao. A aplicao vai invocar o procedimento spPedidoHistoricoINSERT passando o status 6 como um dos
argumentos.

Status 7: pedido entregue


Mais uma vez a aplicao vai cuidar desta mudana de
status, porque dependemos de informaes vindas da
transportadora para providenciar a atualizao do nosso
banco de dados.

Status 8: pedido fechado


O status 8 outro processo automtico. Todo pedido que
chegar ao status 7 (pedido entregue) ou status 103 (pedido
recusado), deve passar automaticamente para o status 8.
Portanto, aqui basta alterarmos o gatilho que criamos
para a tabela de histrico de pedido (Listagem 3), acrescentando este teste. O script atualizado e definitivo
mostrado na Listagem 6.
Assim finalmente terminamos nosso desafio. Apesar
das simplificaes que foram necessrias para fazer este
artigo ficar um pouco mais didtico, os conceitos apresentados aqui so muito usados no dia-a-dia e acredito
que lhes sero teis.

D seu feedback sobre esta edio!


A SQL Magazine tem que ser feita ao seu gosto. Para isso, precisamos saber o
que voc, leitor, acha da revista!
D seu voto sobre este artigo, atravs do link:
www.devmedia.com.br/sqlmagazine/feedback

Feedback
eu
sobre e
s

O conceito de job do SQL Server um pouco diferente


do que se tem em outros SGBDs. Normalmente outros
SGBDs trabalham em ambiente UNIX (ou assemelhados)
e o que se faz, em geral, criar um SHELL script que ser
agendado no CRON, um agendador de tarefas nativo dos
sistemas operacionais da famlia UNIX.

Status 5: nota fiscal emitida

D
s

1 CREATE PROCEDURE dbo.spPedidoSaldo_sel


2 AS
3 BEGIN
4 DECLARE @Pedido
INT
5 DECLARE @Produto
INT
6 DECLARE @QTDPedida NUMERIC(11,2)
7 DECLARE @QTDSaldo NUMERIC(11,2)
8
9 --so pedidos cujo ultimo status igual a 3
10 DECLARE curPedidoItem3 CURSOR FAST_FORWARD FOR
11 SELECT codPedido, codProduto
12 FROM dbo.tblPedidoHistorico
13 GROUP BY codPedido, codProduto
14
H
AVING MAX(codPedidoStatus) = 3
15 OPEN curPedidoItem3
16 FETCH NEXT FROM curPedidoItem3
17 INTO @Pedido, @Produto
18 WHILE @@FETCH_STATUS = 0
19
B
EGIN
20
-saldo eh controlado por lote de produto.
21
SELECT @QTDSaldo = SUM(QTD) FROM dbo.tblSaldoEstoque

22 WHERE codLote in (SELECT codLote
23 FROM dbo.tblLote WHERE codProduto = @Produto)
24
-qtd pedida
25 SELECT @QTDPedida = QTD FROM dbo.tblPedidoDetalhe
26
W
HERE codPedido = @Pedido AND codProduto = @Produto
27
28
I
F @QTDSaldo >= @QTDPedida
29 EXEC dbo.spPedidoHistoricoINSERT @Pedido,@Produto,4
30
31 FETCH NEXT FROM curPedidoItem3
32 INTO @Pedido, @Produto
33 END
34 C
LOSE curPedidoItem3
35 DEALLOCATE curPedidoItem3
36 END

edio
ta

Listagem 4. Procedimento spPedidoSaldo_sel

SQL Magazine - Desafio SQL


25/02/2010 14:31:10

D ESAFIO S QL

Edio 72 - SQL Magazine


SQL73.indb 67

67

25/02/2010 14:31:13

68
SQL73.indb 68

SQL Magazine - Desafio SQL


25/02/2010 14:31:17

Potrebbero piacerti anche