Desafio de SQL
De que trata o artigo?
Desenvolvimento de soluções para problemas cotidianos enfrentados por DBAs e desenvolvedores de aplicações para banco dados.
Para que serve?
Fornecer conceitos de utilização de funcionalidades do padrão SQL ANSI na resolução de problemas enfrentados no dia-a-dia na recuperação de informações do banco de dados.
Em que situação o tema é útil?
Integridade referencial.
Estamos de volta com a coluna Desafio SQL. Para quem nunca a leu, tratamos aqui de problemas enfrentados no dia-a-dia pelos profissionais que trabalham com bancos de dados. E para situarmos estes desafios, a cada artigo contamos um novo capítulo da história da empresa fictícia chamada ItsMyBusiness.
Por curiosidade, lembro aos interessados que esta história começou faz um bom tempo, na Revista #50. Este é o 14o capítulo desta "novela" (no bom sentido, claro).
A ItsMyBusiness é uma empresa de varejo que fez recentemente o seu site de e-commerce. E este site está "bombando"!
Vender mais significa mais dinheiro. Mas do ponto de vista de um banco de dados, representa também um volume maior de transações, maiores cuidados com performance, com armazenamento de dados e disponibilidade do sistema.
Estes são quesitos que devemos ter em mente desde o início da modelagem de qualquer banco. Mas o fato é que a ItsMyBusiness tratou seu e-commerce como se fosse uma experiência e não tomou cuidados básicos com a criação deste sistema.
Se você achou que este cenário se parece com o de algum sistema real com o qual você trabalhou, isso não é mera coincidência. É triste dizer, mas isso é terrivelmente comum. As empresas economizariam muito dinheiro se seguissem noções básicas de projeto.
Bom ou mal, certo ou errado, o fato é que agora a ItsMyBusiness tem que consertar o "motor do seu carro" quando a corrida já está em andamento. Uma série de melhorias e correções de bugs no modelo do banco de dados da empresa tem sido feitas nos últimos meses.
No nosso último desafio, apresentamos uma solução de modelagem para melhorar o controle sobre os pedidos que a ItsMyBusiness recebe. A solução previa o detalhamento dos possíveis status que um pedido poderia ter ao longo da sua história, ou seja, desde o momento em que ele é submetido pelo cliente até o momento em que ele é encerrado pela empresa (seja por qual razão for).
Esta mesma solução incluía a integridade referencial dos dados, ou seja, nosso modelo deveria garantir que os dados registrados no banco fossem 100% consistentes.
O modelo final da base, já incluídas as alterações citadas acima, é apresentado a seguir (Figura 1).
Figura 1. Modelo de dados simplificado da empresa ItsMyBusiness.
O script de criação deste banco de dados está disponível para download no portal da SQL Magazine. O script apresenta versões para rodar em SQL SERVER, DB2, ORACLE e FIREBIRD.
Voltando ao nosso assunto, para sorte da empresa ItsMyBusiness, o DBA que ela contratou, que no caso é você, é um cara muito cuidadoso.
Antes de implementar esta solução, o DBA abriu seu caderno de anotações e viu a seguinte frase escrita 100 vezes em letras garrafais:
“NUNCA FAREI ALTERAÇÕES NO MEU AMBIENTE DE PRODUÇÃO ANTES DE VALIDAR MINHAS SOLUÇÕES EM UM AMBIENTE DE TESTES QUE SIMULE A OPERAÇÃO REAL”.
Então ele passou o script de alteração da base para a equipe de testes, que depois de avaliar dezenas de casos de teste, apresentou o seguinte veredito:
“Por razões desconhecidas, o modelo em análise permite a inserção manual de informações inconsistentes na tabela tblPedidoStatus. O problema foi observado quando fizemos inserção de dados usando uma declaração SQL do tipo INSERT”.
Xiiii... a casa caiu!
Na verdade, ainda não caiu, porque a alteração não foi para produção e é para isso mesmo que fazemos testes meticulosos antes de qualquer implementação.
Já sabemos qual é o problema, pois os testadores não só disseram que o modelo “deu pau”. Eles disseram detalhadamente o que eles estavam fazendo quando o erro foi observado.
O que houve foi o seguinte: foram executadas várias declarações de inserção de dados na tabela dbo.tblPedidoHistorico. Algumas delas deveriam ser aceitas e outras deveriam ser rejeitadas. Chamamos isso de casos de testes.
Na Listagem 1 vemos quatro casos de teste que deveriam ser rejeitados.
Listagem 1. Os testes de rejeição .
1 -- Inserção de código de pedido inexistente
2 --=====> Insert REJEITADO (CORRETO)
3 INSERT INTO dbo.tblPedidoHistorico
4 (codPedido, codProduto, codPedidoStatus, Observacao)
5 VALUES (1000, 1,1, 'nao existe pedido # 1000')
6
7 -- Inserção de código de produto inexistente
8 --=====> Insert REJEITADO (CORRETO)
9 INSERT INTO dbo.tblPedidoHistorico
10 (codPedido, codProduto, codPedidoStatus, Observacao)
11 VALUES (1, 2000 ,1, 'nao existe produto # 2000')
12
13 -- Insercao de código de status inexistente
14 --=====> Insert REJEITADO (CORRETO)
15 INSERT INTO dbo.tblPedidoHistorico
16 (codPedido, codProduto, codPedidoStatus, Observacao)
17 VALUES (1, 1, 3000, 'nao existe status # 3000')
18
19 -- Insercao com produto que não pertence ao pedido
20 --=====> Insert ACEITO (ERRADO!!!!!!!!!!!!!)
21 INSERT INTO dbo.tblPedidoHistorico
22 (codPedido, codProduto, codPedidoStatus, Observacao)
23 VALUES (1, 8, 1, 'o produto # 8 nao faz parte do pedido # 1')
Nos três primeiros, tentamos inserir códigos que não existem (linhas 1 a 22 da Listagem 1) e todos eles foram corretamente rejeita
...