Desvendando o SQL - Parte VI - Estruturas Condicionais e de Repetição
Estamos de volta para hoje falar de mais um assunto sobre a linguagem SQL. Em nosso último artigo mostramos como funcionam as VIEWS, acompanhe esse artigo em Desvendando o SQL - Parte V - Visões, e também os outros artigos de nossa série, os links estão sempre no final de nossos artigos. Hoje vamos falar um pouco sobre as instruções condicionais e instruções de repetição. Boa leitura e estudos
Em determinadas situações nos deparamos com consultas que para obtermos um resultado dependemos de outro ou precisamos que determinada instrução se repita algumas vezes, é exatamente nessas situações que utilizamos as instruções condicionais (CASE, IF) e as instruções de repetição (WHILE).
INSTRUÇÕES CONDICIONAIS (IF)
Com uma sintaxe simples esta expressão impõe uma condição para execução de uma instrução SQL. Se a condição retorna TRUE (Verdadeiro) a instrução é executada. Caso se deseje a execução de uma instrução quando a condição não for satisfeita, retornando FALSE (Falso), incluímos a palavra chave ELSE, e o que nessa clausula será executado.
Sintaxe
IF <Condição>
Bloco de instruções
[ELSE
Bloco de instruções]
A construção apresentada IF...ELSE pode ser usada em procedimentos armazenados (veremos em breve) e em consultas ad hoc. Inclusive podemos aninhar os blocos de IF...ELSE, colocando um dentro do outro.
Exemplos
A. Expressões Simples
--O exemplo a seguir tem uma expressão booliana simples (1=1) que é verdadeira e, portanto, imprime a primeira instrução.
IF 1 = 1 PRINT 'Expressão é verdadeira'
ELSE PRINT 'Expressão é falsa' ;
--O exemplo a seguir tem uma expressão booliana simples (1=2) que é falsa e, portanto, imprime a segunda instrução.
IF 1 = 2 PRINT 'Expressão é verdadeira'
ELSE PRINT 'Expressão é falsa' ;
GO
B. Usando uma consulta como parte de uma expressão booliana. O exemplo a seguir executa uma consulta como parte da expressão booliana. Vamos descobrir se existem mais de 5 produtos com a categoria de bebidas.
USE DBEstoque;
GO
IF (SELECT COUNT(*)
FROM
TBProduto p inner join
TBSubcategoria s ON s.CD_SUB = p.CD_SUB
WHERE s.CD_CATEGORIA = 1) > 5
PRINT 'Existem mais de 5 produtos com a categoria Bebidas'
ELSE
PRINT 'Existem 5 ou menos produtos com a categoria Bebidas' ;
GO
C. Usando um bloco de instrução.
O exemplo a seguir executa uma consulta como parte da expressão booliana e depois executa blocos de instrução ligeiramente diferentes com base no resultado da expressão booliana. Cada bloco de instrução começa com BEGIN e termina com END. Caso a instrução seja somente de uma linha não há necessidade do bloco BEGIN...END.
GO
DECLARE
@AvgCount decimal(8,2),
@ProdCount int,
@Count int
set @Count = (SELECT COUNT(*)
FROM
TBProduto p inner join
TBSubcategoria s ON s.CD_SUB = p.CD_SUB
WHERE s.CD_CATEGORIA = 1)
IF @Count > 5
BEGIN
SET @ProdCount =
(SELECT COUNT(*)
FROM
TBProduto p inner join
TBSubcategoria s ON s.CD_SUB = p.CD_SUB
WHERE s.CD_CATEGORIA = 1);
SET @AvgCount = AVG(@ProdCount);
PRINT 'Existem ' + CAST(@ProdCount AS varchar(3)) + ' com a categoria Bebidas'
PRINT 'A média de produtos com contagem maior que 5 é: ' + CAST(@AvgCount AS varchar(8)) + '.';
END
ELSE
BEGIN
SET @ProdCount =
(SELECT COUNT(*)
FROM
TBProduto p inner join
TBSubcategoria s ON s.CD_SUB = p.CD_SUB
WHERE s.CD_CATEGORIA = 1);
SET @AvgCount = AVG(@ProdCount);
PRINT 'A média de produtos com contagem menor ou igual a 5 é: ' + CAST(@AvgCount AS varchar(8)) + '.' ;
END ;
GO
D.Usando instruções IF...ELSE aninhadas
DECLARE @Numero int;
SET @Numero = 50;
IF @Numero > 100
PRINT 'O número é grande';
ELSE
BEGIN
IF @Numero < 10
PRINT 'O número é pequeno.';
ELSE
PRINT 'O número é mediano.';
END ;
GO
INSTRUÇÕES CONDICIONAIS (CASE)
Essa expressão avalia uma lista de condições e retorna uma dos vários resultados possíveis. A expressão CASE tem dois formatos possíveis e ambos dão suporte ao argumento ELSE (opcional):
- A expressão simples que compara uma expressão com um conjunto de expressões;
- A expressão que avalia um conjunto de expressões;
- A expressão case pode ser usada em qualquer instrução que permita uma expressão válida, como SELECT, UPDATE, DELETE e SET e em cláusulas como SELECT LIST, IN, WHERE, ORDER BY e HAVING. Como o IF o CASE também permite aninhamentos até o 10º nível
Expressão CASE simples
CASE <expressão de entrada>
WHEN Condição1 THEN Resultado
WHEN Condição2 THEN Resultado [ ...n ]
[ELSE Resultado]
END
Expressão CASE pesquisada
CASE
WHEN <expressão de entrada1> THEN Resultado
WHEN <expressão de entrada2> THEN Resultado [ ...n ]
[ELSE Resultado]
END
Expressão CASE Simples
Essa expressão compara a expressão de entrada com cada condição apresentada por equivalência, caso seja equivalente o resultado correspondente será apresentado.
Expressão CASE pesquisada
Essa expressão avalia em separado cada expressão da clausula WHEN e verifica se a mesma é verdadeira e retorna o resultado da clausula THEN correspondente.
Ambas as expressões, simples e pesquisada, atendem algumas condições:
· Somente uma verificação de igualdade é permitida (somente na expressão simples);
· A ordem de avaliação é respeitada como apresentada;
· Retorna o resultado correspondente como TRUE;
· Se nenhuma das condições atenderem a expressão de entrada retorna o resultado do ELSE, caso tenha sido especificado, caso contrário, retorna NULL.
Exemplos
Usando uma instrução SELECT com uma expressão CASE simples. Dentro de uma instrução SELECT, uma expressão CASE simples é permitida somente para uma verificação de igualdade; nenhuma outra comparação é feita. O exemplo a seguir usa a expressão CASE para alterar a exibição dos status dos produtos para torná-las mais compreensíveis.
GO
SELECT CD_REFERENCIA, DESC_PRODUTO,
CASE ST_PRODUTO
WHEN 'A' THEN 'Ativo'
WHEN 'I' THEN 'Inativo'
END AS ST_PRODUTO
FROM TBProduto
ORDER BY CD_REFERENCIA
GO
CD_REFERENCIA DESC_PRODUTO ST_PRODUTO
------------- -------------------------------------------------- ----------
1001 Whisky 08 Anos Ativo
1002 Whisky 12 Anos Ativo
1003 Vinho Ativo
2001 Arroz Branco Ativo
2002 Feijão Carioca Ativo
3001 Leite Longa Vida Ativo
3002 Leite Longa Vida Desnatado Ativo
4010 Macarrão Parafuso Ativo
4020 Macarrão Talharim Ativo
6100 Pêssego em Calda Ativo
6200 Ervilha Ativo
6300 Milho Verde Ativo
(12 linha(s) afetadas)
Usando uma instrução SELECT com uma expressão CASE pesquisada. Dentro de uma instrução SELECT, a expressão CASE pesquisada é permitida para valores a serem substituídos no conjunto de resultados com base nos valores de comparação. O exemplo exibe o preço da lista como um comentário de texto com base na faixa de preços de um produto.
GO
SELECT DESC_PRODUTO, QTD_ESTOQUE,
CASE
WHEN VLR_UNITARIO < 5 THEN 'Menor que R$ 5,00'
WHEN VLR_UNITARIO >= 5 and VLR_UNITARIO < 25 THEN 'Menor que R$ 25,00'
WHEN VLR_UNITARIO >= 25 and VLR_UNITARIO < 100 THEN 'Menor que R$ 100,00'
ELSE 'Maior que R$ 100,00'
END as Preco
FROM
TBEstoque e inner join
TBProduto p on p.cd_produto = e.cd_produto
ORDER BY DESC_PRODUTO ;
GO
Usando CASE em uma cláusula ORDER BY. O exemplo usa a expressão para determinar a ordem de classificação das linhas com base no valor da coluna fornecido.
SELECT CD_REFERENCIA, DESC_PRODUTO
FROM TBProduto
ORDER BY
CASE ST_PRODUTO WHEN 'A' THEN ST_PRODUTO END,
CASE ST_PRODUTO WHEN 'I' THEN ST_PRODUTO END DESC;
GO
SELECT DESC_PRODUTO, QTD_ESTOQUE, SGL_UNIDADE, VLR_UNITARIO
FROM
TBEstoque e inner join
TBProduto p on p.cd_produto = e.cd_produto inner join
TBUnidade u on u.CD_UNIDADE = e.CD_UNIDADE
ORDER BY CASE WHEN DTH_MOVIMENTO < getdate() THEN VLR_UNITARIO
ELSE DESC_PRODUTO END;
Usando CASE em uma instrução UPDATE. O exemplo usa a expressão para determinar o valor definido para a coluna VLR_UNITARIO dos produtos, aplicando um acréscimo de 10, 15 ou 20% de acordo com o valor e caso contrário, somente 5%. A cláusula OUTPUT é usada para exibir os valores de antes e depois da alteração.
GO
UPDATE TBEstoque
SET VLR_UNITARIO =
( CASE
WHEN VLR_UNITARIO < 10.00 THEN VLR_UNITARIO * 1.10
WHEN VLR_UNITARIO >= 10.00 and VLR_UNITARIO < 50.00 THEN VLR_UNITARIO * 1.15
WHEN VLR_UNITARIO >= 50.00 THEN VLR_UNITARIO * 1.20
ELSE VLR_UNITARIO * 1.05
END
)
OUTPUT Deleted.CD_ESTOQUE, Deleted.VLR_UNITARIO AS ValorAnterior,
Inserted.VLR_UNITARIO AS ValorAtual
INSTRUÇÕES DE REPETIÇÃO
Vamos falar nesse artigo do laço de repetição WHILE, existe também o CURSOR, mas para esse vamos futuramente dedicar um artigo exclusivo.
A instrução WHILE define uma condição para executar repetidamente uma ou várias instruções em bloco. Enquanto a condição especificada for verdadeira a repetição acontece. Internamente podemos controlar o WHILE com o BREAK, parando a execução, e o CONTINUE, continuando a execução.
Sintaxe
WHILE Condição
{ bloco de instruções | BREAK | CONTINUE }
No aninhamentos de instruções WHILE o BREAK encerrará sempre o bloco WHILE mais interno prosseguindo para o próximo mais externo e assim sucessivamente.
Exemplos
Instrução WHILE simples.
DECLARE @VAR INT
SET @VAR = 0
WHILE @VAR < 10
BEGIN
PRINT 'O NÚMERO É: ' + CAST(@VAR AS VARCHAR(3))
SET @VAR = @VAR + 1
END
PRINT 'O NÚMERO FINAL É: ' + CAST(@VAR AS VARCHAR(3))
Usando BREAK E CONTINUE. No exemplo abaixo, enquanto valor unitário médio for menor que R$ 50,00 a instrução vai atualizar o peso para o dobro e depois selecionar o mais alto, se for maior que R$ 2000,00 então para o loop, se não continuará dobrando o preço até satisfazer a condição e em seguida exibe uma mensagem.
GO
WHILE (SELECT AVG(VLR_UNITARIO) FROM TBEstoque) < 50
BEGIN
UPDATE TBEstoque
SET VLR_UNITARIO = VLR_UNITARIO * 2
SELECT MAX(VLR_UNITARIO) FROM TBEstoque
IF (SELECT MAX(VLR_UNITARIO) FROM TBEstoque) > 2000
BREAK
ELSE
CONTINUE
END
PRINT 'Muito alto para o mercado';
Por hoje ficamos por aqui, espero que tenham gostado, caso tenha ficado dúvidas sintam-se a vontade para perguntar, comentar, sugerir. No próximo artigo estaremos de volta com um assunto que é muito utilizado nas instruções SQL, a conversão de valores, então vamos mostrar como utilizar o CAST e o CONVERT. Não percam.
Grande abraço e até lá.
Artigos anteriores:
Comentários