我正在创建一个 MySQL 数据库。我有两个不同的表:Sales( id, idoftheproduct, quantity
) 和 Supplies( id, idoftheproduct, quantity
)。我想要一个触发器,每当我们添加新销售或新供应时,它都会增加或减少名为 Stock( idoftheproduct, quantity
)的不同表的值
问问题
4326 次
2 回答
1
简而言之,不要。而是创建一个视图:
CREATE VIEW Stock
AS
SELECT IDofTheProduct, SUM(Quantity) AS Quantity
FROM ( SELECT IDofTheProduct, Quantity
FROM Supplies
UNION ALL
SELECT IdOfTheProduct, -Quantity
FROM Sales
) t
GROUP BY IDofTheProduct;
这样,无论您的基础表更改您的视图都会更改。这在更新/插入期间开销较小,并且始终准确,即使触发器由于某种原因没有触发。
编辑
抱歉,我忘记了 MySQL 不允许视图中的子查询。一种解决方案是创建一个新视图来使用而不是子查询:
CREATE VIEW SalesAndSupplies
AS
SELECT 'Supplies' AS `Type`,
IDofTheProduct,
Quantity
FROM Supplies
UNION ALL
SELECT 'Sales' AS `Type`,
IDofTheProduct,
-Quantity
FROM Sales;
CREATE VIEW Stock
AS
SELECT IDofTheProduct, SUM(Quantity) AS Quantity
FROM SalesAndSupplies
GROUP BY IDofTheProduct;
于 2013-06-10T15:51:51.197 回答
0
具有视图的解决方案是一个很好的解决方案,但随着时间的推移,它往往会变得更慢,尤其是如果您有大量的销售和供应数据,因为您总是计算它。
因此,如果您决定通过触发器实现它,那么您必须至少有四个触发器(在两个表上插入和删除)。由于它们都更新了库存,因此最好将部分代码分解为存储过程。
更新库存的存储过程
CREATE PROCEDURE sp_update_stock(IN pid INT, IN qty DECIMAL(11, 3))
INSERT INTO stock (idoftheproduct, quantity)
VALUES (pid, qty)
ON DUPLICATE KEY UPDATE quantity = quantity + qty;
idoftheproduct
如果在执行时不存在带有 的行,则将创建该行。否则它将更新以反映更改。
现在触发
CREATE TRIGGER tg_sales_insert
AFTER INSERT ON sales
FOR EACH ROW
CALL sp_update_stock(NEW.idoftheproduct, -1 * NEW.quantity);
CREATE TRIGGER tg_supplies_insert
AFTER INSERT ON supplies
FOR EACH ROW
CALL sp_update_stock(NEW.idoftheproduct, NEW.quantity);
CREATE TRIGGER tg_sales_delete
AFTER DELETE ON sales
FOR EACH ROW
CALL sp_update_stock(OLD.idoftheproduct, OLD.quantity);
CREATE TRIGGER tg_supplies_delete
AFTER DELETE ON supplies
FOR EACH ROW
CALL sp_update_stock(OLD.idoftheproduct, -1 * OLD.quantity);
现在您可以在 Sales and Supplies 中插入和删除。
INSERT INTO Supplies VALUES (NULL, 1, 100), (NULL, 1, 50), (NULL, 1, 75);
INSERT INTO Sales VALUES (NULL, 1, 2),(NULL, 1, 10), (NULL, 1, 5);
DELETE FROM Sales WHERE id = 1;
DELETE FROM Supplies WHERE id = 3;
如果看看stock
就会看到
| IDOFHE产品 | 数量 | ----------------------------------------- | 1 | 135 |
这是SQLFiddle演示
于 2013-06-11T04:02:40.877 回答