2016-12-31 2 views
1

Работал над этим часами .. так близко.MySQL Trigger From Previous Row

CREATE TRIGGER `sold_diff` BEFORE INSERT ON `inventory_history` 
FOR EACH ROW begin 
declare prev_quantity int(11) default 0; 

select quantity 
into prev_quantity 
from inventory_history 
limit 1; 

set NEW.sold = prev_quantity - NEW.quantity; 
end 

Вот результат:

enter image description here

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

Желаемый результат:

enter image description here

Я думаю select quantity into prev_quantity является виновником, но я не могу собрать из работоспособной альтернативы.

редактировать: здесь есть sqlfiddle - http://sqlfiddle.com/#!9/6cd76/2/0

ответ

2

Проблема заключается ваш LIMIT всегда читает первую строку в таблице, поскольку порядок по умолчанию является первичным ключом, по возрастанию. Так prev_quantity всегда 100.

Чтобы получить последнего количества, вам нужно использовать:

select quantity 
into prev_quantity 
from inventory_history 
order by id desc 
limit 1; 

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

ID SKU Quantity Sold 
15 Filter 40  10 
16 Filter 30  20 

Поскольку обе вставки следующим образом: «50» имеет последнее количество перед вычислением Продано.

Проданная Расчет 50-40 = 10 для ID 15 и 50-30 = 20 для ID 16.

Единственный способ защиты от этого является блокировка таблицы во время вставки:

LOCK TABLE inventory_history WRITE; 
INSERT INTO inventory_history VALUES (...); 
UNLOCK TABLES; 

Я не рекомендую это делать, если вы хотите поддерживать параллельные ВСТАВКИ с хорошей пропускной способностью.

+0

Большое спасибо и за дополнительную осторожность. Думаю, мне нужно немного изменить его, чтобы привязать к дополнительным столбцам, чтобы предотвратить это – bbruman