2016-02-19 21 views
0

您好堆栈溢出的聪明的头脑,双回路与复杂的更新

今天我花了4小时试图进行更新的命令,会阻止我必须填写一个表,150行,每行3列。

实现这一点,我创建了以下update命令:

UPDATE storage SET Quantity = 
(SELECT SUM(delivery_data.Quantity) FROM delivery_data, delivery, product 
WHERE delivery_data.ID_Delivery = delivery.ID AND delivery.ID_Store = storage.ID_Store AND 
storage.ID_Store = 5 AND delivery_data.ID_Product = product.ID AND product.ID = 1) 
- IFNULL((SELECT SUM(purchase.Quantity) FROM purchase, sale, employee, product 
WHERE purchase.ID_Sale = sale.ID AND sale.ID_employee = employee.NIF 
AND employee.ID_Store = storage.ID_Store AND storage.ID_Store = 5 
AND purchase.ID_Product = product.ID AND product.ID = 1), 0) WHERE storage.ID_Store = 5 
AND storage.ID_Product = 1; 

^遗憾的吸引力代码,但它是一个很长的更新命令,我真的不知道把它的最好办法。

无论如何,如果你认为它是相关的,那么这里就是发生了什么事情: 我有很多的表格,这些表格创建了一个交付和购买公司的设置(交付是公司购买的产品,是客户购买的产品),我想通过计算每件商店有多少产品已经送到商店,然后计算出每个商店有多少存货(公司有多家商店) 。

上面的命令工作正常,但是,你可能会说它只适用于商店5和产品1,并把它的所有5家门店和30种产品的工作,我会复制和粘贴150倍,更改值。

(尽管这样做很可能会比试图更快地找到如何做一个双回路在MySQL中,总体来说可能是最好的,如果我学这种东西。)

所以呀,上班围绕这个问题,我写了一个从我在网上找到的循环的碎片的双循环,因为我并不完全知道它们是如何工作的。这是给我麻烦代码:

DELIMITER $$ 
    CREATE PROCEDURE update_storage() 

     BEGIN 
      DECLARE x INT Default 1; 
      DECLARE y INT Default 1; 
      store: LOOP 

       product: LOOP 

       UPDATE storage SET Quantity = (SELECT DISTINCT delivery_data.Quantity FROM delivery_data, delivery, product WHERE delivery_data.ID_Delivery = delivery.ID AND delivery.ID_Store = storage.ID_Store AND storage.ID_Store = 5 AND delivery_data.ID_Product = product.ID AND product.ID = 1) - IFNULL((SELECT DISTINCT purchase.Quantity FROM purchase, venda, employee, product WHERE purchase.ID_Venda = venda.ID AND venda.ID_employee = employee.NIF AND employee.ID_Store = storage.ID_Store AND storage.ID_Store = 5 AND purchase.ID_Product = product.ID AND product.ID = 1), 0) WHERE storage.ID_Store = 5 AND storage.ID_Product = 1; 

       SET y = y + 1; 
       IF y = 31 THEN 
        LEAVE product; 
       END IF; 
       ITERATE product; 
      END LOOP product; 

      SET x = x + 1; 
      IF x = 6 THEN 
       LEAVE store; 
      END IF; 
      ITERATE store; 
     END LOOP store; 
    END $$ 
    DELIMITER ; 

从我测试了一下,似乎对店1 30种产品的工作,然后将其卡住,我必须重新启动MySQL控制台。如果我将X值更改为默认值2,3等,那么我只需要手动运行1次循环5次,但就像我以前说过的那样,要了解如何使用做一个双循环。

TL; DR什么让我上面的停止变量y的第一次运行后,工作双循环?我是一个白痴吗?在MySQL中是不可能的双循环?帮助表示赞赏。

+0

在子查询中使用DISTINCT似乎很奇怪。对于给定的'(ID_Store,ID_Product)',似乎将有多个交付。考虑到'delivery'和'delivery_data'之间的一对多关系,得到一个DISTINCT值列表似乎不正确。我知道这个问题是关于在一个循环内循环的,但是我被困在看起来错误的UPDATE语句中。 – spencer7593

+0

@ spencer7593哦,你是对的。老实说,更新命令里有这么多东西,我很难知道我在做甚么:P – RaKXeR

+0

@ spencer7593修正了它,我想。 – RaKXeR

回答

0

经过一番搜索,我发现:我没有重置“y”变量,所以它始终在第一次存储后以31开头。如果有人看着这个寻找如何做一个双循环,这里是一般语法:

DELIMITER $$ --basically means what character(s) are used to finalize a command, which is ; by default 
    CREATE PROCEDURE whateveryouwanttonamethis() 

     BEGIN 
      DECLARE x INT Default 1; 
      DECLARE y INT; 
      LOOP1: LOOP 
       SET y = 1; 
       LOOP2: LOOP 

        --What you whish to do with the loop, using X and Y as if they were fields of a table containing values 

        SET y = y + 1; 
        IF y = 999 THEN --replace 999 with the amount of times you want the inner loop to run for 
         LEAVE LOOP2; 
        END IF; 
       ITERATE LOOP2; 
       END LOOP LOOP2; 

      SET x = x + 1; 
      IF x = 999 THEN --replace 999 with the amount of times you want the outter loop to run for 
       LEAVE LOOP1; 
      END IF; 
      ITERATE LOOP1; 
     END LOOP LOOP1; 
    END $$ 
    DELIMITER ;