如何使用触发器来增加或减少mysql中的库存

时间:2013-06-10 15:08:26

标签: mysql sql triggers

我正在创建一个MySQL数据库。我有两个不同的表:销售(id, idoftheproduct, quantity)和供应(id, idoftheproduct, quantity)。我想要一个触发器,无论何时我们添加新的销售或新的供应,它都会增加或减少另一个名为Stock(idoftheproduct, quantity)的表的值

2 个答案:

答案 0 :(得分:1)

总之,不要。而是创建一个view

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;

<强> Example on SQL Fiddle

答案 1 :(得分: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);

现在您可以在销售和供应中插入和删除。

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会看到

| IDOFTHEPRODUCT | QUANTITY |
-----------------------------
|              1 |      135 |  

这是 SQLFiddle 演示