我有一个小的声明,递减一个值:
UPDATE cart_items SET quantity = quantity - 1
WHERE cart_id = {$cart_id} AND id = {$cart_item_id}
但如果该值在减量后变为0,那么SQL是否可以删除该行?如果是这样,那么我想重新计算与该购物车匹配的行数:
SELECT FROM cart_items WHERE cart_id = {$cart_id}
如果行数为零,我想从另一个表中删除该记录,如下所示:
DELETE FROM cart WHERE id = {$cart_id}
目前似乎需要多个查询来执行此操作,但是这一切都可以在单个SQL语句中完成吗?
答案 0 :(得分:2)
简短的回答是,如果不将额外的查询包含在触发器或过程中,则无法实现。
您可以在交易中执行此操作,但不需要SELECT
,但需要3次查询:
START TRANSACTION;
UPDATE cart_items
SET quantity = quantity - 1
WHERE cart_id = {$cart_id}
AND id = {$cart_item_id};
DELETE
FROM cart_items
WHERE quantity = 0
AND cart_id = {$cart_id}
AND id = {$cart_item_id};
DELETE c
FROM cart c
LEFT JOIN cart_items ci
ON ci.cart_id = c.id
WHERE c.id = {$cart_id}
AND ci.cart_id IS NULL;
COMMIT;
最后DELETE
将购物车加入cart_items,如果找不到购物车,则会删除购物车(cart_items字段为NULL
)。
我已经包含了可用的标识符以加快DELETE
的速度,虽然它们没有它们应该没问题。它只会查找并选择任何其他数量0项或空车。
答案 1 :(得分:0)
我认为即使您将使用触发器,也无法在一个查询中执行所有操作,因为您将收到错误:
CREATE TABLE cart_items (cart_id int key, quantity int);
INSERT INTO cart_items VALUES (1, 1), (2, 2);
-- Create trigger
delimiter |
CREATE TRIGGER update_cart_items AFTER UPDATE ON cart_items
FOR EACH ROW
BEGIN
DELETE FROM cart_items WHERE quantity = 0;
END;
|
delimiter ;
现在,如果你要运行更新查询:
UPDATE cart_items SET quantity = quantity - 1 WHERE cart_id = 1;
您将收到错误:
ERROR 1442 (HY000): Can't update table 'cart_items' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
这就是我认为你应该使用少量查询的原因......