SQL Server 2012 – Logical Functions e mais economia de código


logic

Boa noite 🙂

Outro post básico e rápido sobre funções lógicas (do mesmo grupo das já conhecidas estruturas lógicas, que envolvem WHILE, IF, CASE)…

Duas agradáveis adições foram realizadas no SQL Server 2012. Duas funções lógicas que já são velhas conhecidas para quem já programa(ou): IIF e CHOOSE.

IIF

(Documentação Oficial na MSDN para maior apronfudamento)

Também conhecido como IF ternário, nada mais, no contexto de algumas linguagens de programação, uma forma mais organizada de se fazer realizar uma escolha condicional entre dois valores utilizando uma expressão.

Estrutura:

IIF (boolean_expression, true_value, false_value) ou em bom português IIF (expressão_booleana, valorSeVerdadeiro, valorSeFalso)

É justamente pela estrutura que vem o nome de IF Ternário, por possui três elementos (parâmetros) em sua condição.

Seguem três exemplos pra posteriores comentários.

USE TEMPDB
GO

DECLARE @Idade INT = 22
-- DECLARE @Idade INT = 10 /* Pra quem quiser testar */

--> Exemplo com IIF

SELECT IIF(@Idade >= 18,'Pode tirar carteira','Não pode tirar carteira') as TesteIIF

--> Exemplo com CASE

SELECT
	TesteCase = 
	CASE
		WHEN @Idade >= 18 THEN 'Pode tirar carteira'
		ELSE 'Não pode tirar carteira'
	END

--> Exemplo com IF-ELSE

	IF (@Idade >= 18) 
	BEGIN
		SELECT 'Pode tirar carteira' AS TesteIF
	END
	ELSE
		SELECT 'Não pode tirar carteira' AS TesteIF

Em suma, como IF não pode ser utilizado em comandos SELECT deliberadamente para realizar condições, sendo utilizado mais em Stored Procedures e Funções, IIF serve como sintaxe alternativa para a função CASE, que faz exatamente o que a instrução IIF faria em uma instrução SELECT.  O que acho bacana nesse comando:

  • Sintaxe simples, limpa e direta (embora de começo pareça complexa);
  • Segue padrões .net (ao trabalhar com Integration Services, por exemplo, é uma cláusula largamente utilizada para faze comparações) e de outras linguagens;
  •  Economia de código, facilitando legibilidade;

Tem só um pequeno detalhe… Não estou dizendo que é um substituto pra CASE, por um simples e humilde motivo, e lógico ainda por cima:

CASE, assim como IF (em seu devido lugar) permitem mais de duas expressões lógicas. IIF é X, se não for X, ah meu amigo, é Y. Sem choro nem vela.

Códigos para expressar o sentimento:

SELECT
	TesteCase = 
	CASE
		WHEN @Idade >= 18 THEN 'Pode tirar carteira'
		WHEN @Idade BETWEEN 15 AND 17 THEN 'Falta pouco pra poder tirar!'
		ELSE 'Não pode tirar carteira'
	END

Logo, é necessário avaliar qual a melhor construção para a sua lógica.

CHOOSE

Documentação Inicial na MSDN

Resumindo, assim como o IIF, o CHOOSE é outra cláusula condicional que pode, dependendo do caso, substituir o CASE. É mais uma construção bastante utilizada em .net e inclusive no Integration Services (Olha a MS casando particularidades de produtos “distintos” da suite  do SQL Server aos poucos aí!)

Vamos falar antes de sua construção:

CHOOSE (index, val_1, val_2 [, val_n ])

A função CHOOSE vai retornar exatamente o valor que corresponde ao index passado no primeiro parâmetro:

DECLARE @Nota INT = 4
SELECT CHOOSE (@Nota,'Péssimo','Ruim','Normal','Bom','Sensacional') AS Nota

DECLARE @Nota INT = 7
SELECT CHOOSE (@Nota,'Péssimo','Ruim','Normal','Bom','Sensacional') AS NotaNULA

O protocolo é claro. Existem cinco parâmetros dentro do CHOOSE. O primeiro vale um (1) e o último cinco (5). O número (index) passado é Quatro (4) então ele vai buscar o quarto valor nos parâmetros. No segundo exemplo, como ele não acha o parâmetro cujo valor é sete (7) ele simplesmente retorna NULO. A mesma coisa vale para o ZERO.
Outra aplicação prática:

DECLARE @T AS TABLE(
	VALOR INT
)

INSERT INTO @T (VALOR) VALUES (1),(2),(3),(4),(5),(6),(7)

SELECT VALOR, CHOOSE (VALOR,'DOMINGO','SEGUNDA','TERÇA','QUARTA','QUINTA','SEXTA','SABADO') AS Nota
FROM @T

But, contudo, todavia, todos os parâmetros devem ser do mesmo tipo, pois caso um dos valores esteja fora do padrão, ocorrerá um erro na execução. Veja só:

DECLARE @T AS TABLE(
	VALOR INT
)

INSERT INTO @T (VALOR) VALUES (1),(2),(3),(4),(5),(6),(7)

SELECT VALOR, CHOOSE (VALOR,'DOMINGO','SEGUNDA','TERÇA','QUARTA','QUINTA','SEXTA','SABADO',9) AS Nota
FROM @T

(6 row(s) affected)
Msg 245, Level 16, State 1, Line 7
Conversion failed when converting the varchar value ‘DOMINGO’ to data type int.

Enfim, alguns pontos positivos:

  • As mesmas vantagens do IIF

Minha única observação sobre a função é que poderia ser MUITO, mas MUITO útil caso fosse possível utilizar intervalos de valores, como é possível com CASE (usando BETWEEN por exemplo) e outras possibilidades lógicas. Acho o comando um pouco limitado no geral assim como o IIF. Mas tem quem gostará, com certeza. Qual a melhor escolha? A resposta pra praticamente qualquer coisa no SQL Server é: It’s depends.

Espero ter sido claro e ter ajudado alguém. Se sim, Já valeu a postagem.

Obrigado pela visita and…

Keep Querying !

[]’s

,

Leave a Reply

Your email address will not be published. Required fields are marked *