如何在UPDATE上更新具有相同prodID的行?

时间:2013-05-22 17:44:15

标签: mysql triggers

我收到以下错误: “无法在存储的函数/触发器中更新表'Product',因为它已被调用此存储函数/触发器的语句使用。”

CREATE TRIGGER `SalesDB`.`updateSum` AFTER UPDATE ON SalesDB.Product FOR EACH ROW
BEGIN
  DECLARE totalStock INT;

  SELECT SUM(stock) 
      INTO totalStock
      FROM Product
      WHERE Product.prodID= NEW.prodID;

  UPDATE Product SET StockSum = totalStock
      WHERE  prodID = NEW.prodID;
END;

我知道有一个递归问题,但我该如何做这样的事情呢?有没有办法使用触发器来做这种事情?是否应该在存储过程中完成,以及如何在Update Product事件上运行stroed过程?

我需要更新产品库存,然后通过所有具有相同prodID的行计算SUM并更新所有行的SumTotal字段。

1 个答案:

答案 0 :(得分:1)

更新遗憾的是,由于触发器实施的限制,您无法在MySql中执行此操作。

可能的选择是:

  1. 创建存储过程并在每次更新Product table
  2. 后调用它
  3. 将stockSum存储在单独的表格(例如ProductStock)中,使用触发器(INSERT,UPDATE)更新stockSum值,在连接的Product和ProductStock上创建视图
  4. 如果可以接受某些延迟,请使用MySql事件或cron作业更新Product表中的stockSum
  5. 恕我直言最佳方法是2分离产品和产品库表:

    ProductStock可能会是这样的

    CREATE TABLE ProductStock
    (
      prodID int NOT NULL PRIMARY KEY,
      stockSum decimal(12, 3)
    );
    

    现在触发

    CREATE TRIGGER tg_product_update
    AFTER UPDATE ON Product 
    FOR EACH ROW
    CALL sp_updateProductStock(NEW.prodID);
    
    CREATE TRIGGER tg_product_insert
    AFTER INSERT ON Product 
    FOR EACH ROW
    CALL sp_updateProductStock(NEW.prodID);
    

    和存储过程

    CREATE PROCEDURE sp_updateProductStock(IN ProductID INT)
    REPLACE INTO ProductStock (prodID, stockSum) 
    SELECT ProductID, 
           (SELECT SUM(COALESCE(stock, 0)) 
              FROM Product
             WHERE prodID = ProductID);
    

    最后是一个视图

    CREATE VIEW vw_Product AS
    SELECT p.id, p.prodID, ... , p.stock, s.stockSum
      FROM Product p JOIN ProductStock s
        ON p.prodID = s.prodID
    

    这是 SQLFiddle 示例