Dicas T-SQL – IF … ELSE – BEGIN … END

Fala pessoal,

Nesse post vou mostrar um caso que encontrei em um cliente onde o IF … ELSE impactou no resultado de uma query! #gogogo


YouTube – Vídeo:

Segue abaixo um vídeo que gravei no YouTube mostrando na prática a execução dos scripts desse post:

https://www.youtube.com/watch?v=bIXkJ9sZLkc


Pergunta:

Mas antes, quero fazer um TESTE com você:

Dado o script abaixo, qual será o resultado dessa query?

OBS: Não vale roubar e executar o script OK! Pense por 1 ou 2 minutos e escolha a sua alternativa antes de continuar a leitura do post.

(A) ERRO! Pois não utilizou o BEGIN … END no ELSE.

(B) Vai retornar apenas o SELECT (1).

(C) Vai retornar os SELECT (1) e (2).

(D) Vai retornar os SELECT (1) e (3).

(E) Vai retornar os SELECT (1), (2) e (3).

(F) Não vai retornar nenhum SELECT.


Resposta:

Obviamente tem uma pegadinha do malandro aí. Vamos analisar cada uma das alternativas:

“(A) ERRO! Pois não utilizou o BEGIN … END no ELSE.

Essa é só pra tentar complicar um pouco, pois não vai gerar erro. O BEGIN … END são OPCIONAIS, ou seja, você utiliza se quiser. Logo, a alternativa está INCORRETA.

“(B) Vai retornar apenas o SELECT (1).

Se eu consegui te enganar, você pode ter escolhido essa alternativa, mas ela também está INCORRETA.

“(C) Vai retornar os SELECT (1) e (2).

Por eliminação poderíamos desconsiderar essa, pois não faz sentido retornar o SELECT do IF e do ELSE na mesma execução. Ele vai retornar sempre um OU outro, nunca os dois OK. Logo, a alternativa está INCORRETA.

“(D) Vai retornar os SELECT (1) e (3).”

Essa é a alternativa CORRETA!!!

Vamos analisar novamente o IF … ELSE:

No IF utilizei o BEGIN … END. No ELSE eu não utilizei de propósito e aqui está a pegadinha do malandro.

Quando NÃO utilizamos o BEGIN … END, o SQL Server entende que o ELSE possui apenas uma instrução, ou seja, somente o SELECT (2) faz parte do ELSE e o SELECT (3) está fora do IF … ELSE.

Eu particularmente prefiro SEMPRE utilizar o BEGIN … END para evitar esse tipo de situação. Olha só como ficaria muito mais claro entender o que pertence ou não ao IF … ELSE. #ficaadica

“(E) Vai retornar os SELECT (1), (2) e (3).

Assim como a alternativa (C), também não faz sentido ele retornar todos os três SELECTS. Logo, a alternativa está INCORRETA.

“(F) Não vai retornar nenhum SELECT.

Por eliminação poderíamos desconsiderar essa, pois vai retornar pelo menos um SELECT (IF ou ELSE). Logo, a alternativa está INCORRETA.

“Ahh Luiz, mas isso é muito bobo, não vou encontrar nada disso na prática no meu dia a dia!!!”

Será mesmo??? Agora vamos para o Caso do Dia a Dia!


Caso do Dia a Dia:

Vou simular um cenário para reproduzir o erro que encontrei em um cliente. Primeiro vamos criar uma tabela chamada “HISTORICO_ESTOQUE” e deixar ela vazia. Repare que utilizamos uma PRIMARY KEY para evitar duplicidades na tabela OK.

Depois vou criar uma outra tabela “ESTOQUE_DIA_ATUAL” para armazenar o estoque do dia atual e inserir alguns registros nela.

Agora imagine que temos um JOB que executa diariamente para fazer a carga na tabela “HISTORICO_ESTOQUE” com os dados do estoque do dia atual (tabela “ESTOQUE_DIA_ATUAL”).

O JOB utiliza o script abaixo:

Contudo, o cliente informou que estava dando erro de “duplicate key”. Ele tinha analisado, mas não conseguiu encontrar o problema.

(3 rows affected)

Msg 2627, Level 14, State 1, Line 70

Violation of PRIMARY KEY constraint ‘PK__HISTORIC__8CD1B715497217B0’.

Cannot insert duplicate key in object ‘dbo.HISTORICO_ESTOQUE’. The duplicate key value is (2021-01-12, 1, 100).

The statement has been terminated.

Ao analisar o JOB, identifiquei que o problema estava no ELSE. É o mesmo caso do nosso exemplo, pois o cliente achou que o DELETE e o INSERT faziam parte do ELSE, mas na verdade era apenas o DELETE e o último INSERT estava sendo executado sempre. Essa era a causa do erro de “duplicate key”.

Por fim, segue abaixo a correção que sugerimos no JOB. Bastava inserir o BEGIN … END no ELSE para delimitar os dois comandos. Depois desse ajuste ele voltou a executar com sucesso!


Espero que tenha gostado e que isso também possa ser útil no seu dia a dia. Até o próximo post!

Me siga no LinkedIn e YouTube para ficar por dentro das novidades.

Abraço,

Luiz Vitor França Lima

Consultor SQL Server

2 comentários em “Dicas T-SQL – IF … ELSE – BEGIN … END

Deixe uma resposta para José Dız (Porto SQL)Cancelar resposta