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á.




Comentários

Postagens mais visitadas