触发循环使currentStock保持为0

时间:2016-01-17 17:44:56

标签: mysql

所以我试图找出一个触发器,自动将订单中的成分(dhh_purchaseorder)添加到表dhh_ingredients中。它应该从dhh_purchaseorderingredient中获取新的有序数量并将其转储到orderAmount变量中。然后它应该将当前可用库存与新库存中的订购数量相结合。然后它应该更新成分表并设置正确成分的新量,但由于某种原因,它会将currentStock列的成分保持为0。

这是我的触发器:

BEGIN

DECLARE orderStatus, orderIngredientName VARCHAR(50);
DECLARE finished INTEGER DEFAULT 0;
DECLARE currentStock, newStock DECIMAL(10,2);
DECLARE orderNo, orderAmount int(10);
DECLARE lookupCursor CURSOR FOR SELECT INGREDIENTingredientName from dhh_purchaseorderingredient WHERE dhh_purchaseorderingredient.PURCHASEpurchaseOrderNo = NEW.purchaseOrderNo;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

SET orderNo = NEW.purchaseOrderNo;
SET orderStatus = NEW.status;

IF(orderStatus = "DELIVERED") THEN

OPEN lookupCursor;

update_loop: LOOP
    FETCH lookupCursor INTO orderIngredientName;
    IF finished = 1 THEN
    LEAVE update_loop;
    END IF;

    SET orderAmount = (SELECT amount from dhh_purchaseorderingredient WHERE dhh_purchaseorderingredient.PURCHASEpurchaseOrderNo = orderNo AND dhh_purchaseorderingredient.INGREDIENTingredientName = orderIngredientName);
    SET currentStock = (SELECT currentStock FROM dhh_ingredient WHERE ingredientName = orderIngredientName);
    SET newStock = currentStock + orderAmount;

    INSERT INTO temp VALUES(currentStock);

    UPDATE dhh_ingredient
    SET currentStock = newStock
    WHERE ingredientName = ingredientName;

END LOOP update_loop;

CLOSE lookupCursor;

END IF;
END

1 个答案:

答案 0 :(得分:0)

这部分是答案,部分是建议采用更好的方法。

I believe stored procedures are a very bad idea的许多原因之一是它们很难调试。在这种情况下,要弄清楚分配给各种库存量变量的值是不容易的。

更好的方法是使用更新的查询 - 无需SP变量。测试它真的很容易;只需执行并检查结果。通过在SP中使用这样的查询,可以从代码中消除不正确的查询逻辑,从而允许您将SP压缩到重要的位 - 更新。

幸运的是,MySQL通过其多表更新语法提供了一种通过连接进行更新的方法。

这就是查询的样子:

UPDATE dhh_ingredient, dhh_purchaseorderingredient
SET = currentStock = currentStock - amount
WHERE dhh_purchaseorderingredient.INGREDIENTingredientName = orderIngredientName
AND ingredientName = orderIngredientName
AND dhh_purchaseorderingredient.PURCHASEpurchaseOrderNo = NEW.purchaseOrderNo
AND NEW.status = 'DELIVERED';

不需要局部变量或任何循环,因为更新查询执行连接,并且NEW值直接用于查询。

因此,您的整个存储过程变得简单:

BEGIN

    UPDATE dhh_ingredient, dhh_purchaseorderingredient
    SET = currentStock = currentStock - amount
    WHERE dhh_purchaseorderingredient.INGREDIENTingredientName = orderIngredientName
    AND ingredientName = orderIngredientName
    AND dhh_purchaseorderingredient.PURCHASEpurchaseOrderNo = NEW.purchaseOrderNo
    AND NEW.status = 'DELIVERED';

END

易于理解,维护和调试 - 更好的解决方案。