2016-02-04 6 views
5

У меня есть крошечное заявление, в котором декрементах значение:SELECT, UPDATE, DELETE с одним SQL-запросом?

UPDATE cart_items SET quantity = quantity - 1 
WHERE cart_id = {$cart_id} AND id = {$cart_item_id} 

Но это было бы возможно для SQL, чтобы удалить строку, если это значение становится равным 0 после декремента? Если это так, я тогда хочу пересчитать количество строк, соответствующих эту телегу:

SELECT FROM cart_items WHERE cart_id = {$cart_id} 

И если число строк равно нуль, я хочу, чтобы удалить эту запись из другой таблицы, например, так:

DELETE FROM cart WHERE id = {$cart_id} 

На данный момент для этого требуется несколько запросов, но может ли это быть сделано в одном выражении SQL?

+4

Вам понадобится хранимая процедура. –

+1

Это невозможно сделать в одном запросе. – rbedger

ответ

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

Нет, но это не хранимая процедура. Она просто завернута в один звонок. – Arth

+1

Это может быть решение, но я полагаю, что это не совсем то, что ожидает @daninthemix ... –

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. 

Вот почему я думаю, вы должны использовать несколько запросов ...

Смежные вопросы