在MySQL中创建一个更复杂的存储过程时,我遇到了一个奇怪的CASE语句问题。我简化了程序来说明这个问题。我在每个循环中选择三样东西来澄清问题:count
变量,CASE之前的modTemp
变量,然后是一个表示所采取的CASE路径的数字。
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//
现在我使用CALL AddPlants(3);
这是我的结果:
预期输出
count = 1, modTemp = 1, 1
count = 2, modTemp = 2, 2
count = 3, modTemp = 0,3
实际输出
count = 1, modTemp = 1, 1
count = 2, modTemp = 2, Error: modTemp = 2
count = 3, modTemp = 0, 1
每次计数和modTemp都是正确的值。但是,在第二个循环中,modTemp为2,但不输入CASE 2。在第三个循环中,modTemp为0,但进入CASE 1。知道这里发生了什么吗?
混合使用CASE
的两种方法。你可以这样写:
CASE
WHEN <expression1> THEN <result1>;
WHEN <expression2> THEN <result2>;
...
END CASE
计算每个表达式,并执行第一个为真表达式的相应结果。或:
CASE <expression>
WHEN <val1> THEN <result1>;
WHEN <val2> THEN <result2>;
...
END CASE
将<expression>
与每个值进行比较,并对第一个匹配的值执行相应的结果。
您使用了第二种语法,但是您的值也包含比较。所以它们都是0
(用于false
)或1
(用于true
),这就是您将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;
是不是应该更像
CREATE PROCEDURE `AddPlants` (IN plantNum int)
开始DECLARE count 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;
结束//