Resumo : neste tutorial, você aprenderá como usar CASE
instruções MySQL para construir instruções condicionais complexas dentro de procedimentos armazenados.
Introdução à instrução CASE do MySQL
Além da IF
instrução, o MySQL fornece uma instrução condicional alternativa chamada CASE
instrução para construir instruções condicionais em procedimentos armazenados. As CASE
instruções tornam o código mais legível e eficiente.
A CASE
declaração tem duas formas: declarações simples CASE
e pesquisadas .CASE
Observe que se você quiser adicionar a lógica if-else a uma instrução SQL, use a CASE
expressão que difere da CASE
instrução descrita neste tutorial.
Instrução CASE simples
A seguir está a sintaxe básica da CASE
instrução simples:
CASE case_value
WHEN when_value1 THEN statements
WHEN when_value2 THEN statements
...
[ELSE else-statements]
END CASE;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Nesta sintaxe, a CASE
instrução simples compara sequencialmente case_value
is com when_value1
, when_value2
e assim por diante até encontrar uma correspondência.
Quando CASE
encontra um case_value
igual a a when_value
, ele é executado statements
na THEN
cláusula correspondente.
Se CASE
a instrução não puder encontrar nenhum when_value
igual a case_value
, ela executará na else-statements
cláusula ELSE
se a ELSE
cláusula for fornecida.
Quando a ELSE
cláusula não existe e CASE
não consegue encontrar nenhum when_value
igual a case_value
, ocorre um erro:
Case not found for CASE statement
Linguagem de código: PHP ( php )
Observe que case_value
pode ser um valor literal ou uma expressão. O statements
pode consistir em uma ou mais instruções SQL e não pode estar vazio.
Para evitar o erro quando the case_value
não é igual a any when_value
, você pode usar um BEGIN...END
bloco vazio na ELSE
cláusula, como segue:
CASE case_value
WHEN when_value1 THEN ...
WHEN when_value2 THEN ...
ELSE
BEGIN
END;
END CASE;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
A CASE
instrução simples testa a igualdade ( =
), você não pode usá-la para testar a igualdade com NULL
; porque NULL
= NULL
retorna FALSE
.
Exemplo simples de instrução CASE
O procedimento armazenado a seguir ilustra como usar a CASE
instrução simples:
DELIMITER $$
CREATE PROCEDURE GetCustomerShipping(
IN pCustomerNUmber INT,
OUT pShipping VARCHAR(50)
)
BEGIN
DECLARE customerCountry VARCHAR(100);
SELECT
country
INTO customerCountry FROM
customers
WHERE
customerNumber = pCustomerNUmber;
CASE customerCountry
WHEN 'USA' THEN
SET pShipping = '2-day Shipping';
WHEN 'Canada' THEN
SET pShipping = '3-day Shipping';
ELSE
SET pShipping = '5-day Shipping';
END CASE;
END$$
DELIMITER ;
Linguagem de código: PHP ( php )
Como funciona.
O GetCustomerShipping()
procedimento armazenado aceita dois parâmetros: pCustomerNumber
como IN
parâmetro e pShipping
como OUT
parâmetro.
No procedimento armazenado:
Primeiro, selecione o país do cliente na customers
tabela pelo número do cliente inserido.
Em segundo lugar, use o CASE
extrato simples para determinar o tempo de envio com base no país do cliente. Se o cliente localizar em USA
, o tempo de envio é de 2-day shipping
. Se o cliente localizar em Canada
, o tempo de envio é de 3-day shipping
. Os clientes de outros países têm 5-day shipping
.
O fluxograma a seguir demonstra a lógica da instrução CASE para determinar o tempo de envio:
Esta instrução chama o procedimento armazenado com o ID de cliente 112 e retorna as informações de envio:
CALL GetCustomerShipping(112,@shipping);
SELECT @shipping;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Saída:
+----------------+
| @shipping |
+----------------+
| 2-day Shipping |
+----------------+
1 row in set (0.00 sec)
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Declaração CASE pesquisada
A declaração simples CASE
permite apenas comparar um valor com um conjunto de valores distintos.
Para realizar correspondências mais complexas, como intervalos, você usa a CASE
instrução pesquisada. A CASE
afirmação pesquisada é equivalente à IF
afirmação, porém é muito mais legível que a IF
afirmação.
Aqui está a sintaxe básica da CASE
instrução pesquisada:
CASE
WHEN search_condition1 THEN statements
WHEN search_condition1 THEN statements
...
[ELSE else-statements]
END CASE;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Nesta sintaxe, searched CASE
avalia cada um search_condition
na WHEN
cláusula até encontrar uma condição que avalie como e TRUE
, em seguida, executa a THEN
cláusula correspondente statements
.
Se não search_condition
for avaliado como TRUE
, CASE
será executado else-statements
na ELSE
cláusula se uma ELSE
cláusula estiver disponível.
Semelhante à CASE
instrução simples, se você não especificar uma ELSE
cláusula e nenhuma condição for TRUE
, o MySQL gerará o mesmo erro:
Case not found for CASE statement
Linguagem de código: PHP ( php )
O MySQL também não permite que você tenha um vazio statements
na cláusula THEN
ou ELSE
. Se você não quiser manipular a lógica na ELSE
cláusula enquanto evita que o MySQL gere um erro caso não search_condition
seja verdadeiro, você pode usar um BEGIN...END
bloco vazio na ELSE
cláusula.
Exemplo de instrução CASE pesquisada
O exemplo a seguir demonstra como usar um CASE
extrato pesquisado para obter o status de entrega de um pedido com base no número de dias de espera:
DELIMITER $$
CREATE PROCEDURE GetDeliveryStatus(
IN pOrderNumber INT,
OUT pDeliveryStatus VARCHAR(100)
)
BEGIN
DECLARE waitingDay INT DEFAULT 0;
SELECT
DATEDIFF(requiredDate, shippedDate)
INTO waitingDay
FROM orders
WHERE orderNumber = pOrderNumber;
CASE
WHEN waitingDay = 0 THEN
SET pDeliveryStatus = 'On Time';
WHEN waitingDay >= 1 AND waitingDay < 5 THEN
SET pDeliveryStatus = 'Late';
WHEN waitingDay >= 5 THEN
SET pDeliveryStatus = 'Very Late';
ELSE
SET pDeliveryStatus = 'No Information';
END CASE;
END$$
DELIMITER ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Como funciona.
O procedimento armazenado GetDeliveryStatus()
aceita um número de pedido como IN
parâmetro e retorna o status de entrega como OUT
parâmetro.
Primeiro, calcule o número de dias entre a data solicitada e a data de envio.
Segundo, determine o status da entrega com base no número de dias de espera usando o CASE
extrato pesquisado:
- Se o número de dias de espera for zero, a entrega será pontual.
- Quando o número de dias de espera está entre 1 e 5, a entrega está atrasada.
- Quando o número de dias de espera é superior a 5 dias, a entrega atrasa muito.
- Se o número de dias de espera for NULL ou então, a entrega terá o status de sem informação especificada na
ELSE
cláusula.
Esta instrução usa o procedimento armazenado GetDeliveryStatus()
para obter o status de entrega do pedido 10100
:
CALL GetDeliveryStatus(10100,@delivery);
SELECT @delivery;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Saída:
+-----------+
| @delivery |
+-----------+
| Late |
+-----------+
1 row in set (0.00 sec)
Linguagem de código: JavaScript ( javascript )
Instrução MySQL CASE vs. instrução IF
Ambas as instruções IF
e CASE
permitem executar um bloco de código com base em uma condição específica. Escolher entre IF
ou CASE
às vezes é apenas uma questão de preferência pessoal.
Aqui estão algumas diretrizes gerais:
- Uma instrução simples
CASE
é mais legível e eficiente do que umaIF
instrução quando você compara uma única expressão com um intervalo de valores exclusivos. - Ao verificar expressões complexas com base em vários valores, a
IF
instrução fica mais fácil de entender. - Se você usar a
CASE
instrução, deverá certificar-se de que pelo menos uma dasCASE
condições seja atendida. Caso contrário, você precisará definir um manipulador de erros para capturar o erro. Observe que você não precisa fazer isso com aIF
instrução. - Em algumas situações, você pode usar ambos
IF
eCASE
para tornar o código mais legível e eficiente.
Resumo
- Use uma
CASE
instrução simples para avaliar uma expressão específica em relação a uma série de valores possíveis e executar as ações correspondentes. - Use uma
CASE
instrução pesquisada para avaliar diversas condições individualmente, permitindo um código mais flexível.