问题
While creating a more complex stored procedure in MySQL, I encountered a weird problem with my CASE statement. I have simplified my procedure to show the issue. I am selecting three things per loop to clarify the problem: the count variable, the modTemp variable before the CASE, and then a number representing which CASE path was taken.
DELIMITER //
CREATE PROCEDURE `AddPlants` (IN plantNum int)
BEGIN
DECLARE count int;
DECLARE modTemp int;
SET count = 1;
WHILE count <= plantNum DO
SELECT CONCAT('count = ', count);
SET modTemp = count % 3;
SELECT CONCAT('modTemp = ', modTemp);
CASE modTemp
WHEN modTemp = 1 THEN
SELECT 1;
WHEN modTemp = 2 THEN
SELECT 2;
WHEN modTemp = 0 THEN
SELECT 3;
ELSE
SELECT CONCAT('Error: modTemp = ', modTemp);
END CASE;
SET count = count + 1;
END WHILE;
END//
Now I use CALL AddPlants(3); Here are my results:
Expected output
count = 1, modTemp = 1, 1
count = 2, modTemp = 2, 2
count = 3, modTemp = 0, 3
Actual output
count = 1, modTemp = 1, 1
count = 2, modTemp = 2, Error: modTemp = 2
count = 3, modTemp = 0, 1
Each time, count and modTemp are the correct values. However, on the second loop, modTemp is 2 but does not enter CASE 2. And in the third loop, modTemp is 0 but goes into CASE 1. Any ideas what is happening here?
回答1:
You're mixing the two ways to use CASE. You either write:
CASE
WHEN <expression1> THEN <result1>;
WHEN <expression2> THEN <result2>;
...
END CASE
This evaluates each expression, and executes the corresponding result for the first true one. Or:
CASE <expression>
WHEN <val1> THEN <result1>;
WHEN <val2> THEN <result2>;
...
END CASE
This compares <expression> to each value, and executes the corresponding result for the first one that matches.
You used the second syntax, but your values also contain a comparison. So they're all either 0 (for false) or 1 (for true), and that's what you're comparing modTemp to. Change to:
CASE modTemp
WHEN 1 THEN
SELECT 1;
WHEN 2 THEN
SELECT 2;
WHEN 0 THEN
SELECT 3;
ELSE
SELECT CONCAT('Error: modTemp = ', modTemp);
END CASE;
回答2:
Shouldn't it be more like
CREATE PROCEDURE `AddPlants` (IN plantNum int)
BEGIN DECLARE count int; DECLARE modTemp int;
SET count = 1;
WHILE count <= plantNum DO
SELECT CONCAT('count = ', count);
SET modTemp = count % 3;
SELECT CONCAT('modTemp = ', modTemp);
CASE modTemp
WHEN 1 THEN
SELECT 1;
WHEN 2 THEN
SELECT 2;
WHEN 0 THEN
SELECT 3;
ELSE
SELECT CONCAT('Error: modTemp = ', modTemp);
END CASE;
SET count = count + 1;
END WHILE;
END//
来源:https://stackoverflow.com/questions/24297146/mysql-case-select-not-behaving-as-expected