如何添加两个游标值并更新表

Posted

技术标签:

【中文标题】如何添加两个游标值并更新表【英文标题】:How to add two cursor values and UPDATE the table 【发布时间】:2016-01-05 13:43:03 【问题描述】:

我想在vehicle_idvehicleno 应该相同的位置添加两个游标值,然后更新表。

示例:

1.value from cur2 , totkm_t  
2.value from cur3 , totkm_l  

我想添加这两个,即

totkm_f = totkm_t + ktotm_l

然后

update fuelavg SET totkm=totkm_f where vid=vid_l; 

我也希望对其他存储泵进行此类添加,但我的存储过程返回空值。

DELIMITER $$
DROP PROCEDURE IF EXISTS `searchvehicle`.`fuelavg`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `fuelavg`(IN startdate DATE,  IN enddate DATE)
BEGIN
    DECLARE vname_c VARCHAR(40);
    DECLARE vnostring_c varchar(30);
    DECLARE vowner_c varchar(40);
    DECLARE vid_c,vmax_c,vmin_c,vcmpny_c,vtype_c INT;
    DECLARE done INT DEFAULT FALSE;      
DROP TABLE IF EXISTS fuelavg;
 CREATE TABLE fuelavg
 (
   id int not null auto_increment primary key,  
   vid int,
   vname varchar(40),
   vnostring varchar(30),
   v_type int,
   vowner varchar(40), 
   store int,
   pump int,
   other int,
   totfuel int,
   totkm int,
   vehavrg float,
   cmpnyavg int,
   maxavg int,
   minavg int
);    
     BLOCK1: BEGIN 
     DECLARE CUR1 CURSOR FOR SELECT vehicle_owner.vid,vehicle_owner.vname, vehicle_owner.vowner,vehicle_owner.vnostring,vehicle_owner.vtype,vehicle_owner.vcompnyavg,vehicle_owner.maxavg,vehicle_owner.minavg FROM vehicle_owner;
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE; 
     OPEN CUR1;
     READ_LOOP: LOOP     
     FETCH CUR1 INTO vid_c,vname_c,vowner_c,vnostring_c,vtype_c,vcmpny_c,vmax_c,vmin_c;
     IF done THEN LEAVE READ_LOOP;
     END IF;
     SET autocommit=0;       
     INSERT INTO fuelavg(vid,vname,vnostring,vowner,v_type,cmpnyavg, maxavg,minavg)values(vid_c,vname_c,vnostring_c,vowner_c,vtype_c,vcmpny_c,vmax_c,vmin_c);   
     END LOOP;
     CLOSE CUR1;
     END BLOCK1;
     BLOCK2: BEGIN  
     DECLARE vid_t,totkm_t,store_t,pump_t,other_t INT;
     DECLARE vnostring_t VARCHAR(30);
     DECLARE indate_t,outdate_t DATE DEFAULT FALSE;  
     DECLARE vid_l,totkm_l,store_l,pump_l,other_l INT;
     DECLARE vnostring_l VARCHAR(30); `enter code here`
     DECLARE vid_f,totkm_f,store_f,pump_f,other_f INT;
     DECLARE vnostring_f VARCHAR(30); 
     DECLARE done INT DEFAULT FALSE;     
     DECLARE CUR2 CURSOR FOR SELECT logentry.vid,logentry.vnostring,sum(logentry.totkm),sum(logentry.other),sum(logentry.store),sum(logentry.pump) FROM logentry WHERE indate>=startdate and indate<=enddate group by vid,vnostring;      
     DECLARE CUR3 CURSOR FOR SELECT logentry.vid,logentry.vnostring,sum(logentry.totkm),sum(logentry.store),sum(logentry.other),sum(logentry.pump) FROM LOGENTRY WHERE INDATE<=(SELECT MAX(INDATE) FROM LOGENTRY WHERE TANKFULL=1 AND INDATE<startdate)AND tankfull=1 GROUP BY VID;    
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;   
     OPEN CUR2;  
     OPEN CUR3;     
     READ_LOOP: LOOP   
     FETCH CUR2 INTO vid_t,vnostring_t,totkm_t,other_t,store_t,pump_t;  
     IF done THEN LEAVE READ_LOOP;
     END IF;   
     FETCH CUR3 INTO vid_l,vnostring_l,totkm_l,other_l,store_l,pump_l;  
     IF done THEN LEAVE READ_LOOP;
     END IF;  
     UPDATE fuelavg SET totkm=(totkm_t+totkm_l),other=(other_t+other_l),store=(store_t+store_l),pump=(pump_t+pump_l) WHERE vid=vid_t AND vnostring=vnostring_t;
     IF done THEN LEAVE READ_LOOP;
     END IF;  
     SET autocommit=1; 
     END LOOP;
     CLOSE CUR2;
     CLOSE CUR3;
     END BLOCK2;
     select * from fuelavg; 

此处附加的输出文件,当前上述查询显示空值。

【问题讨论】:

请为您的问题提供正确的格式。 你刚刚浪费了你的 50 赏金。 【参考方案1】:

最后,我的努力取得了成果。以下是我通过添加两个游标值来更新表格的代码。

   DELIMITER $$
  DROP PROCEDURE IF EXISTS `searchvehicle`.`fuelavg2`$$
 CREATE DEFINER=`root`@`localhost` PROCEDURE `fuelavg2`(IN startdate DATE, IN enddate DATE)
BEGIN
   DECLARE vname_c VARCHAR(40);
   DECLARE vnostring_c varchar(30);
   DECLARE vowner_c varchar(40);
   DECLARE vid_c,vmax_c,vmin_c,vcmpny_c,vtype_c INT;
   DECLARE done INT DEFAULT FALSE;      
   DROP TABLE IF EXISTS fuelavg;
CREATE TABLE fuelavg
 (
   id int not null auto_increment primary key,  
   vid int,
   vname varchar(40),
   vnostring varchar(30),
   v_type int,
   vowner varchar(40), 
   store int,
   pump int,
   other int,
   totfuel int,
   totkm int,
   vehavrg int,
   cmpnyavg int,
   maxavg int,
   minavg int
   );    
   BLOCK1: BEGIN 
   DECLARE CUR1 CURSOR FOR SELECT vehicle_owner.vid,vehicle_owner.vname,vehicle_owner.vowner,vehicle_owner.vnostring,vehicle_owner.vtype,vehicle_owner.vcompnyavg,vehicle_owner.maxavg,vehicle_owner.minavg FROM vehicle_owner;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE; 
   OPEN CUR1;
   READ_LOOP: LOOP     
   FETCH CUR1 INTO vid_c,vname_c,vowner_c,vnostring_c,vtype_c,vcmpny_c,vmax_c,vmin_c;
   IF done THEN LEAVE READ_LOOP;
   END IF;
   SET autocommit=0;       
   INSERT INTO fuelavg(vid,vname,vnostring,vowner,v_type,cmpnyavg, maxavg,minavg)values(vid_c,vname_c,vnostring_c,vowner_c,vtype_c,vcmpny_c,vmax_c,vmin_c);   
   END LOOP;
   CLOSE CUR1;
   END BLOCK1;
   BLOCK2: BEGIN  
   DECLARE vid_t,totkm_t,store_t,pump_t,other_t INT;
   DECLARE vnostring_t VARCHAR(30);
   DECLARE indate_t,outdate_t DATE DEFAULT FALSE;  
   DECLARE vid_l,totkm_l,store_l,pump_l,other_l INT;
   DECLARE vnostring_l VARCHAR(30); 
   DECLARE vid_f,totkm_f,store_f,pump_f,other_f INT;
   DECLARE vnostring_f VARCHAR(30); 
   DECLARE vid_a,totfuel_a INT;
   DECLARE vehavrg_a INT;
   DECLARE vnostring_a VARCHAR(30);
   DECLARE done,done3,done2,done5 INT DEFAULT FALSE; 
   DECLARE CUR2 CURSOR FOR SELECT logentry.vid,logentry.vnostring,sum(logentry.totkm),sum(logentry.other),sum(logentry.store),sum(logentry.pump) FROM logentry WHERE indate>=startdate and indate<=enddate group by vid,vnostring;  
   DECLARE CUR4 CURSOR FOR SELECT logentry.vid,logentry.vnostring,sum(logentry.totkm),sum(logentry.other),sum(logentry.store),sum(logentry.pump) FROM logentry WHERE indate>=startdate and indate<=enddate group by vid,vnostring;                
   DECLARE CUR3 CURSOR FOR SELECT logentry.vid,logentry.vnostring,sum(logentry.totkm),sum(logentry.store),sum(logentry.other),sum(logentry.pump) FROM LOGENTRY WHERE INDATE<=(SELECT MAX(INDATE) FROM LOGENTRY WHERE TANKFULL=1 AND INDATE<startdate)AND tankfull=1 GROUP BY VID;              

   OPEN CUR2;   
BLOCK5:BEGIN 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
    OPEN CUR4;
    /* update table by value of traversing the tankfull of last month */
    READ_LOOP5:LOOP          
    FETCH CUR4 INTO vid_t,vnostring_t,totkm_t,other_t,store_t,pump_t;  
    IF done THEN LEAVE READ_LOOP5;
    END IF;         
    UPDATE fuelavg SET totkm=totkm_t,other=other_t,store=store_t,pump=pump_t WHERE vid=vid_t;
    IF done THEN LEAVE READ_LOOP5;     
    END IF;
    END LOOP READ_LOOP5; 
END BLOCK5;
BLOCK3:BEGIN
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done3=TRUE;   
    OPEN CUR3; 
    READ_LOOP3:LOOP
    FETCH CUR3 INTO vid_l,vnostring_l,totkm_l,other_l,store_l,pump_l;  
    IF done3 THEN LEAVE READ_LOOP3;
    END IF; 
    /**********************/
    /* update table by value of traversing the tankfull of last month */
    BLOCK4:BEGIN 
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2=TRUE;  
        READ_LOOP2:LOOP          
        FETCH CUR2 INTO vid_t,vnostring_t,totkm_t,other_t,store_t,pump_t;  
        IF done3 THEN LEAVE READ_LOOP2;
        END IF;         
        UPDATE fuelavg SET totkm=totkm_t+totkm_l,other=other_t+other_l,store=store_t+store_l,pump=pump_t+pump_l WHERE vid=vid_t AND vid=vid_l ;
        IF done2 THEN LEAVE READ_LOOP2;     
        END IF;
        END LOOP READ_LOOP2; 
        END BLOCK4;
    /**********************/
    END LOOP READ_LOOP3; 
    END BLOCK3;
    /* calculate totfuel,averge*/
    BLOCK5:BEGIN 
    DECLARE CUR5 CURSOR FOR SELECT fuelavg.vid,fuelavg.vnostring,(SUM(fuelavg.other) + SUM(fuelavg.pump) + SUM(fuelavg.store)) AS 'tot_fuel',(SUM(fuelavg.totKM)/ (SUM(fuelavg.other)+SUM(fuelavg.pump)+SUM(fuelavg.store))) AS 'veh_avrg' FROM fuelavg group by vid,vnostring;   
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done5=TRUE;  
    OPEN CUR5;   
    READ_LOOP6:LOOP          
    FETCH CUR5 INTO vid_a,vnostring_a,totfuel_a,vehavrg_a;
    IF done5 THEN LEAVE READ_LOOP6;
    END IF;         
    UPDATE fuelavg SET totfuel=totfuel_a,vehavrg=vehavrg_a WHERE vid=vid_a AND vnostring=vnostring_a;
    IF done5 THEN LEAVE READ_LOOP6;     
    END IF;   
    END LOOP READ_LOOP6; 
    CLOSE CUR5; 
    END BLOCK5;
   /**********************/
  CLOSE CUR3;   
  CLOSE CUR2;  
  CLOSE CUR4;  
  END BLOCK2;
 select * from fuelavg;   
 END$$

 DELIMITER ;`

【讨论】:

以上是关于如何添加两个游标值并更新表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 %ROWTYPE 获取游标值

如何在过程中的表中插入游标值

更新触发器以将两个不同表中的数据添加到审计表中

如何获取ListView的项目onItemClick的游标值?

如何在动态SQL(SQL Server)中的Select语句中使用游标值

如何使用外键更新两个表