Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数中的MYSQL循环不工作_Mysql_Sql_Stored Procedures - Fatal编程技术网

函数中的MYSQL循环不工作

函数中的MYSQL循环不工作,mysql,sql,stored-procedures,Mysql,Sql,Stored Procedures,我有一个mysql函数,它将相应地更改记录。但循环只执行一次,并使用此条件离开循环。“如果v_finished=1,则 留下你的股票; 如果结束;” 然而,它应该执行多次。就像在我的测试用例中一样3次 BEGIN DECLARE P_stock int(11); DECLARE P_product int(11); DECLARE V_From_warehouse int(11); DECLARE V_To_warehouse int(11); DECLARE v_finished INTEG

我有一个mysql函数,它将相应地更改记录。但循环只执行一次,并使用此条件离开循环。“如果v_finished=1,则 留下你的股票; 如果结束;”

然而,它应该执行多次。就像在我的测试用例中一样3次

BEGIN

DECLARE P_stock int(11);
DECLARE P_product int(11);
DECLARE V_From_warehouse int(11);
DECLARE V_To_warehouse int(11);
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE V_To_warehouse_stock int(11);
DECLARE V_From_warehouse_stock int(11);



declare cur1 cursor for 
        SELECT material_transfer_details.product_id , material_transfer_details.quantity  FROM
            material_transfers,
            material_transfer_details
        WHERE
            material_transfers.id = material_transfer_details.mtm_id
        AND
            material_transfers.status = 'Y'
        AND 
            material_transfers.id = V_MTM_id;

DECLARE CONTINUE HANDLER 
        FOR NOT FOUND SET v_finished = 1;

SELECT warehouse_from INTO V_From_warehouse FROM material_transfers WHERE id =V_MTM_id; 

SELECT warehouse_to INTO V_To_warehouse FROM material_transfers WHERE id =V_MTM_id;


OPEN cur1;

get_stock: LOOP

 IF v_finished =1 THEN
        LEAVE get_stock;
    END IF;

fetch cur1 into P_product , P_stock;

SELECT quantity INTO V_To_warehouse_stock from stocks where warehouse_id = V_To_warehouse and product_id = P_product;

SELECT quantity INTO V_From_warehouse_stock from stocks where warehouse_id = V_From_warehouse and product_id = P_product;



IF (V_To_warehouse_stock IS NOT NULL)
THEN
    UPDATE 
        stocks SET quantity = quantity - P_stock 
    WHERE
        warehouse_id = V_to_warehouse 
        AND
            product_id = P_product;
ELSE

    INSERT INTO stocks(product_id , warehouse_id , quantity ,status, created_datetime , updated_datetime) values 
        (P_product , V_to_warehouse , 0-P_stock , 'Y', sysdate() , sysdate()); 


END IF;



IF (V_From_warehouse_stock IS NOT NULL)
THEN
    UPDATE 
        stocks SET quantity = quantity + P_stock 
    WHERE
        warehouse_id = V_from_warehouse 
        AND
            product_id = P_product;
ELSE

    INSERT INTO stocks(product_id , warehouse_id , quantity ,status, created_datetime , updated_datetime) values 
        (P_product , V_from_warehouse , P_stock , 'Y', sysdate() , sysdate()); 


END IF;

SET P_stock = 0;
SET P_product = 0;

END LOOP get_stock;

CLOSE cur1;




UPDATE material_transfers SET Status = 'N' WHERE id= V_MTM_id;

UPDATE material_transfer_details SET Status = 'N' WHERE mtm_id = V_MTM_id;

return '00000';

END
两件事:

首先,更改代码

get_stock: LOOP

  SET v_finished = FALSE;

  fetch cur1 into P_product , P_stock;

  IF v_finished =1 THEN
    LEAVE get_stock;
  END IF;
由于您正在执行其他可能使处理程序跳闸的操作,请重置
v_finished
,然后从光标中提取,然后测试是否离开循环

如前所述,如果您没有过早地触发处理程序,您将在完全错误的位置进行测试,并且将在循环中停留太久

接下来。。。确保您理解
选择。。。进入
。我认为它不像你想象的那样

标量子查询是更安全的解决方案:

SET V_To_warehouse_stock = (SELECT quantity from stocks where warehouse_id = V_To_warehouse and product_id = P_product);
如果
选择。。。INTO
不返回任何行,变量的值不变。它保留了它以前的价值(如果存在的话),而这很少是你所期望的

最好避免像这样远距离的恐怖动作,这是一个很容易落入圈套的圈套


有关此效果的示例,请参见。

cur1包含多少行,我的意思是select scrict是否返回任何行。首先检查一次。它返回3行。我已经手动检查过了,
未找到的continue处理程序不仅会作用于一个光标,而且如果
选择warehouse\u to to to V\u warehouse…
没有找到任何行,这显然是您所期望的,因为您在
if(V\u to\u warehouse\u stock不为空)中测试了这一点。
。您可以添加另一个处理程序;您可以在获取新行之前设置一个变量(以便可以在处理程序中检查该变量);或者其他类似的方式。