Fala pessoal!
Nesse artigo eu gostaria de compartilhar com vocês uma dúvida que foi enviada em um grupo de Whatsapp, que era referente à mensagem de erro abaixo quando um analista estava tentando montar um CASE com mais de 10 condições num SELECT:
Statement(s) could not be prepared.
Msg 125, Level 15, State 4, Line 1
Case expressions may only be nested to level 10.
Entendendo e simulando o problema
A consulta em questão era algo tipo isso:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SELECT (CASE Id WHEN 1 THEN 1 WHEN 2 THEN 2 WHEN 3 THEN 3 WHEN 4 THEN 4 WHEN 5 THEN 5 WHEN 6 THEN 6 WHEN 7 THEN 7 WHEN 8 THEN 8 WHEN 9 THEN 9 WHEN 10 THEN 10 WHEN 11 THEN 11 END) AS Teste FROM [DIRCEU-VM\SQL2019].dirceuresende.dbo.Clientes |
Então, vou tentar reproduzir esse cenário no meu ambiente de testes:
Analisando o plano de execução estimado (o real não abre), identificamos que o SQL Server está utilizando o operador “Remote Query” para fazer a consulta e esta foi alterada incluindo vários cases aninhados, conforme o print abaixo:
OK.. consegui simular o erro.. Vou conectar na instância da origem dos dados para testar se essa query vai funcionar local ou se só acontece isso quando os dados vêm de Linked Server:
A mesma consulta funcionou quando conectei na instância local, mesmo com mais de 10 condições no CASE. Ou seja, acabei de comprovar que essa mensagem de erro só acontece quando estamos aplicando um case a partir de dados que vêm de um Linked Server. Consultando dados locais, ou seja, que estão na mesma instância, não temos essa restrição, uma vez que desta vez, o operador utilizado é o Clustered Index Scan ao invés do Remote Query:
Vamos buscar algumas alternativas para aplicar esse CASE e evitar essa mensagem de erro:
Utilizando subquery
Tentei utilizar uma subquery para tentar ignorar essa limitação de mais de 10 condições num case com dados vindo de Linked Server.
Utilizando CTE
Tentei utilizar uma CTE para tentar ignorar essa limitação de mais de 10 condições num case com dados vindo de Linked Server.
Utilizando Múltiplos CASES com COALESCE
Quando tentei utilizar múltiplos cases e uma função COALESCE para juntar os dados dos múltiplos cases em uma única coluna, foi onde consegui sucesso para realizar a consulta:
Utilizando OPENQUERY
Quando tentei utilizar OPENQUERY para consultar os dados remotos e montar o CASE, também tive sucesso para realizar a consulta:
Resumo do post:
- Se a consulta não utilizar Linked Server, não precisa utilizar essa técnica. Pode utilizar quantas condições quiser no mesmo case
- Se a consulta utilizar Linked Server que aponte para a própria instância, não precisa utilizar essa técnica também. Funciona como se fosse uma consulta normal sem linked server.
- A função COALESCE aceita múltiplas condições, então não é limitada a somente 2 cases, podem ser vários (embora a complexidade do código vá aumentando..)
- Você só pode utilizar até 9 condições em cada CASE em cenários onde a consulta é feita em dados remotos
- A utilização do ELSE NULL ao final de cada case é opcional
- Subquery e CTE não resolvem esse problema
- OPENQUERY e OPENROWSET não possuem essa limitação de 10 condições do CASE também
Obrigado pela visita, espero que tenham gostado do post bem objetivo e até mais!
Grande abraço!