0

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

4

2 回答 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;

SQL Fiddle 示例

于 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 回答