I'm getting this error while trying to create a procedure in MySQL:
Error Code: 1337
Variable or condition declaration after cursor or handler declaration
even after doing a lot of Googling I found no relevant solution to my problem. My procedure is as below:
DELIMITER //
CREATE PROCEDURE emp_dates(IN startDate DATE, IN endDate DATE)
BEGIN
DECLARE fromDt DATETIME;
DECLARE toDt DATETIME;
DECLARE done INT DEFAULT FALSE;
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
DECLARE emp VARCHAR(20);
SET fromDt=startDate;
SET toDt=endDate;
OPEN employees;
WHILE fromDt<=toDt DO
REPEAT
FETCH employees INTO emp;
IF NOT done THEN
INSERT INTO new_attendance_2(attid,empid,dt) VALUES(DEFAULT,emp,fromDt);
END IF
UNTIL done END REPEAT;
SET fromDt=DATE_ADD(fromDt, INTERVAL 1 DAY);
LOOP
CLOSE employees;
END
DELIMITER ;
The purpose is to create a procedure which will take two dates as input and insert records in other table for every day that comes in between of those two.
Somebody please help! I appreciate any little help. Thanks a lot in advance.
It's complaining about:
Variable or condition declaration after cursor or handler declaration
So I would be looking at that location, where you do indeed declare variables after the cursor and handler:
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
>> DECLARE emp VARCHAR(20);
If you modify your declarations thus, it should be okay:
DECLARE fromDt DATETIME;
DECLARE toDt DATETIME;
DECLARE done INT DEFAULT FALSE;
DECLARE emp VARCHAR(20);
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
The order has to be, as per here:
Cursor declarations must appear before handler declarations and after variable and condition declarations.
You need to re-order your declarations.
Cursor declarations must appear before handler declarations
and after variable and condition declarations.
http://dev.mysql.com/doc/refman/5.1/en/cursors.html
Related
I need call sp before declaring a cursor. The sp fills a table and then the cursor loop in this tables rows. But workbench does not allow call sp or anything else before declare statements.
create definer=`root`#`%` procedure `usp_tesst`()
begin
declare ordid int;
declare packid int;
declare cstmid int;
declare deltimespanid int;
declare dstrcid int;
declare pcstatus tinyint(1);
declare deliverytime datetime;
declare maxdate datetime;
declare temppackcount int default(0);
call usp_createtemppackages;
-- it says there is a syntax error in here
declare crs cursor for
select * from temppackages....
How should I call this sp ?
DECLARE statements must be first in Stored Procedures.
Consider either - 1) calling usp_createtemppackages before calling usp_tesst 2) integrating usp_createtemppackages functionality into usp_tesst 3) Removing the cursor and iterating the table some other way (which may give a performance increase too as cursors are a bit slow).
You can accomplish what you need as follows:
...
declare maxdate datetime;
declare temppackcount int default(0);
/*call usp_createtemppackages;*/
-- it says there is a syntax error in here
declare crs cursor for
select * from temppackages....
call usp_createtemppackages;
...
SQL Fiddle demo
It's the first time I use cursors and im having issues with the variable 'done'. This variable handles whether the loop iterates over the cursosr or not. When the trigger its executed, the following error happens:
ERROR 1193 (HY000): Unknown system variable 'done'
As far as i see in the mysql cursor documentation, the 'done' variable declaration is correct. Anyone sees the problem?
The trigger:
delimiter //
CREATE TRIGGER `prestamo_positivo` AFTER UPDATE ON `prestamo`
FOR EACH ROW BEGIN
DECLARE aux VARCHAR(10);
DECLARE aux2 CHAR(10);
DECLARE c1 CURSOR FOR SELECT id_cliente FROM PRESTATARIO;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET aux=(SELECT A.id_cliente FROM PRESTATARIO A, PRESTAMO B WHERE A.numero_prestamo=OLD.numero);
IF(NEW.cantidad = 0) THEN
DELETE FROM `prestamo` WHERE numero=OLD.numero;
OPEN c1;
c1_loop: LOOP
fletch c1 into aux2;
IF done THEN LEAVE c1_loop; END IF;
IF(aux = aux2) THEN
INSERT INTO `mensaje`(mensaje, id_usuario) VALUES ("Renegociar prestamos del cliente",aux);
END IF;
END LOOP c1_loop;
CLOSE c1;
END IF;
END; //
If you check the sample code you linked in the question, you can see that done variable is explicitly declared before the continue handler, so you need to do the same. The below excerpt is from the sample code from the link you specified:
DECLARE done INT DEFAULT FALSE; //<= declare done variable here
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
Also, as P.Salmon has already remarked, you cannot modify the table the trigger is declared on, therefore
DELETE FROM `prestamo` WHERE numero=OLD.numero;
line will fail with error 1442.
I created a procedure as below in MySQL workbench 8.0.12 community, win10. A cursor is declared to loop through more than 16000 member's ID in a table to insert their number of orders created in different dates into another table.
Member's IDs and their dates of registration are selected here for the cursor. select distinct BAG,AAA from DICT_ALLE_AAAF where AAA>=Date_Memb_Star. Once I call it call PRO_MIDD_MEMB_AAAA_1('2017/01/01','2019/11/10',60), it only looped through 5 member's IDs and did not report any error. But if I took the while loop out of the procedure and with select Var_BAG on, the cursor loop went selecting more than 200 member's IDs until it asked me to cancel it. Can anyone tell me what is wrong in my code? Many thanks.
delimiter //
create procedure PRO_MIDD_MEMB_AAAA_1
(in Date_Memb_Star date,
in Date_Sale_End date,
in Int_Inte int)
begin
declare Int_Floo int default 0;
declare Int_Ceil int;
declare Int_MembAll int;
declare Int_Loop int default 1;
declare Int_MaxiLoop int;
declare Int_DaySpen int default 30;
declare Int_Done int;
declare Var_BAG varchar(16);
declare Date_Memb_Regi date;
declare Cur_Memb cursor for
select distinct BAG,AAA from DICT_ALLE_AAAF where AAA>=Date_Memb_Star order by BAG;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Int_Done = 1;
truncate table MIDD_MEMB_AAAA;
open Cur_Memb;
read_loop:loop
fetch Cur_Memb into Var_BAG,Date_Memb_Regi;
if Int_Done=1 then
leave read_loop;
end if;
/*select Var_BAG;*/
set Int_MaxiLoop=ceil(datediff(Date_Sale_End,Date_Memb_Regi)/Int_Inte);
set Int_Floo=0;
while Int_Loop<=Int_MaxiLoop do
set Int_Ceil=Int_Floo+Int_Inte;
insert into MIDD_MEMB_AAAA
select Var_BAG,Int_Floo,Int_Ceil,
count(distinct BAK)*(Int_DaySpen/Int_Inte) as Numb_Con_Avg
from OPER_SALE_AAAB
where BAG=Var_BAG
and timestampdiff(hour,Date_Memb_Regi,AAA)/24>Int_Floo
and timestampdiff(hour,Date_Memb_Regi,AAA)/24<=Int_Ceil
and AAB>0;
set Int_Floo=Int_Floo+Int_Inte;
set Int_Loop=Int_Loop+1;
end while;
end loop read_loop;
close Cur_Memb;
end//
delimiter ;
Little oversight: you forgot to reset your variable Int_Loop, so after the first run, it only enters the loop when Int_MaxiLoop has a new maximum value.
Reinitialize it (to 1, I assume) before the loop:
...
set Int_Floo=0;
set Int_Loop=1;
while Int_Loop<=Int_MaxiLoop do ...
How can I use two cursors in the same routine? I am getting "Variable or condition declaration after cursor or handler declaration" error while creating procedure.
I have to use both integer outerDone & innerDone to check whether cursor points to null or not.
I haven't worked on stored-procedure yet. Could anybody sort this problem please. Thanks in advance!!
DELIMITER ##;
create procedure updateStopTimeColumn()
BEGIN
DECLARE outerDone INT DEFAULT 0;
DECLARE vehicle_record CURSOR FOR SELECT `vehicleId` FROM `vehicle`;
DECLARE current_record CURSOR FOR SELECT `id`,`tsTime`,`teTime` FROM `trip` where `vehicleId`=vehId order by `tsTime`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET outerDone = 1;
DECLARE vehId,tripId CHAR(250);
DECLARE currentTsTime,currentTeTime time;
OPEN vehicle_record;
REPEAT
FETCH vehicle_record INTO vehId;
block2 : BEGIN
DECLARE innerDone INT DEFAULT 0;
DECLARE tempTripId CHAR(250);
DECLARE tempTsTime,tempTeTime time;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET innerDone = 1;
OPEN current_record;
FETCH current_record INTO tempTripId, tempTsTime,tempTeTime;
REPEAT
FETCH current_record INTO tripId,currentTsTime,currentTeTime;
UPDATE trip set stopTime=(currentTeTime-tempTsTime) where id=tempTripId and tempTeTime IS NOT NULL;
SET tempTripId=tempId;
SET tempTsTime=currentTsTime;
SET tempTeTime=currentTeTime;
UNTIL innerDone END REPEAT;
END block2;
CLOSE current_record;
UNTIL outerDone END REPEAT;
CLOSE vehicle_record;
END; ##
DELIMITER;
Have you tried moving the
DECLARE vehId,tripId CHAR(250);
DECLARE currentTsTime,currentTeTime time;
statements to before your cursors?
I have the following code that is supposed to return a list of customers that are younger than the provided age parameter and a total count of found records.
My table consists of: columns ID, FIRST_FIRSTNAME, LASTNAME, DATE_OF_BIRTH
I could have easily made a few mistakes in the syntax, logic and formatting of this procedure but forgive me, I am new to this! The following is my sql procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS sample_procedure$$
CREATE PROCEDURE sample_procedure(IN actualinput INT)
BEGIN
DECLARE no_more_customers int(4);
DECLARE l_customer_count int(4);
DECLARE l_id varchar(1);
DECLARE l_first_name varchar(10);
DECLARE l_last_name varchar(10);
DECLARE l_date_of_birth varchar(20);
DECLARE customer_list varchar(250);
DECLARE dateinput DATE;
SET dateinput=DATE_SUB(now(), interval actualinput year);
DECLARE cid CURSOR FOR
SELECT ID, FIRST_FIRSTNAME, LAST_NAME, DATE_OF_BIRTH
FROM customers WHERE DATE_OF_BIRTH >= dateinput;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_customers=1;
SET no_more_customers=0;
SET l_customer_count=0;
OPEN cid;
cid_cursor: REPEAT
FETCH cid INTO l_id, l_first_name, l_last_name, l_date_of_birth; IF no_more_customers THEN
LEAVE cid_cursor;
END IF;
SET customer_list=concat(customer_list, l_id,',',l_first_name,',',l_last_name,',',l_date_of_birth);
SET l_customer_count=1+l_customer_count;
UNTIL no_more_customers
END REPEAT cid_cursor;
CLOSE cid;
SET no_more_customers=0;
SELECT customer_list AS Customers;
SELECT concat(l_customer_count);
END;
$$
I appear to have an error in the method I used to calculate the age of customers, possibly an issue with the method I used to call the cursor and my final list of customers is only returning null.
Thanks in advance...
I can suppose that variable 'customer_list' should be initialized, e.g. -
...
DECLARE customer_list VARCHAR(250) DEFAULT '';
...
because 'SET customer_list = CONCAT(customer_list, ...)' when customer_list is NULL, will return NULL too.
Take advantage of MySQL Stored Procedure Debugger. Hope this feature will help you.