MySQL中CASE WHEN条件不满足仍执行导致字段更新异常问题
问题描述
初始_skus表数据:
sku_id is_available is_quantity quantity 13 1 0 NULL
执行以下UPDATE语句:
UPDATE _skus SET is_available = CASE WHEN is_quantity = 1 AND quantity=0 THEN 0 END WHERE sku_id=13
执行后表数据变为:
sku_id is_available is_quantity quantity 13 0 0 NULL
明明is_quantity = 1 AND quantity=0的条件不成立,is_available却被更新为0。表结构及插入语句如下:
CREATE TABLE `_skus` ( `sku_id` int(11) NOT NULL AUTO_INCREMENT, `is_available` tinyint(1) NOT NULL, `is_quantity` tinyint(1) NOT NULL, `quantity` int(11) NULL DEFAULT NULL, PRIMARY KEY (`sku_id`) USING BTREE ) ENGINE = MyISAM AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; INSERT INTO `_skus` VALUES (13, 1, 0, NULL);
异常原因
问题出在CASE语句的逻辑上:
- 当
is_quantity = 1 AND quantity=0条件不满足时,CASE表达式没有匹配的分支,会返回NULL - 而
is_available字段定义为tinyint(1) NOT NULL,不允许存储NULL值,MySQL会自动把NULL隐式转换为0,最终导致该字段被更新为0。
解决办法
有两种可行的修复方案:
方案1:给CASE语句添加ELSE分支,保留原字段值
当条件不满足时,让CASE返回字段原来的值,避免NULL转换:
UPDATE _skus SET is_available = CASE WHEN is_quantity = 1 AND quantity=0 THEN 0 ELSE is_available -- 条件不满足时保持原数值 END WHERE sku_id=13
方案2:将CASE的条件合并到WHERE子句中
只有当条件满足时才执行更新操作,避免对不符合条件的行做修改:
UPDATE _skus SET is_available = 0 WHERE sku_id=13 AND is_quantity = 1 AND quantity=0
内容的提问来源于stack exchange,提问作者Ziad Nassar
相关产品推荐
相关产品推荐

