My stored procedure is like this ...
DELIMITER $$
DROP PROCEDURE IF EXISTS `tds_dev`.`BlockTokenSheduler`$$
CREATE PROCEDURE `BlockTokenSheduler`(cdate date,shift varchar(20))
BEGIN
declare lo_SERIALNO int;
declare lo_TOKENNUMBER int;
declare lo_ARRIVALTIME time;
declare lo_ADJUSTMENTTIME time;
declare lo_APPOINTMENTTIME time;
declare bt_ADJUSTMENTTIME time;
declare bt_NEXTAPPOINTMENTTIME time;
declare lo_CONSULTATIONTYPE varchar(20);
declare lo_NEXTAPPOINTMENTTIME time;
declare lo_CONSULTATIONSTATUS varchar(20);
declare lo_ACTUALFINISHEDTIME time;
declare lo_SMSSTATUS varchar(20);
declare temp_appTime time;
declare time_diff time;
declare done int;
declare btdone int;
declare btcount int;
declare co int;
Declare btcountcur Cursor for
select ADJUSTMENTTIME,NEXTAPPOINTMENTTIME from tds_tokengeneration where TOKENDATE =cdate and SHIFTID = shift and blockstatus='BT' ORDER BY APPOINTMENTTIME ;
declare continue handler for not found set btdone=1;
open btcountcur;
bt_loop :LOOP
if btdone=1 then
leave bt_loop;
end if;
FETCH btcountcur into bt_ADJUSTMENTTIME,bt_NEXTAPPOINTMENTTIME;
Declare mycur cursor for
select TOKENNUMBER,APPOINTMENTTIME,ADJUSTMENTTIME,CONSULTATIONTYPE,NEXTAPPOINTMENTTIME,CONSULTATIONSTATUS,SMSSTATUS from tds_tokengeneration
where TOKENDATE=cdate and SHIFTID=shift and blockstatus='MT';
declare continue handler for not found set done=1;
open mycur;
time_loop :LOOP
FETCH mycur into lo_TOKENNUMBER,lo_APPOINTMENTTIME,lo_ADJUSTMENTTIME,
lo_CONSULTATIONTYPE,lo_NEXTAPPOINTMENTTIME,lo_CONSULTATIONSTATUS,lo_SMSSTATUS;
if done=1 then
leave time_loop;
end if;
if (lo_ADJUSTMENTTIME >= bt_ADJUSTMENTTIME and lo_APPOINTMENTTIME <= bt_NEXTAPPOINTMENTTIME) or (lo_NEXTAPPOINTMENTTIME >= bt_ADJUSTMENTTIME and lo_NEXTAPPOINTMENTTIME <= bt_NEXTAPPOINTMENTTIME)then
set lo_ADJUSTMENTTIME=bt_NEXTAPPOINTMENTTIME;
if lo_CONSULTATIONTYPE='C' then
set lo_NEXTAPPOINTMENTTIME = ADDTIME(lo_ADJUSTMENTTIME,'00:12:00');
else
set lo_NEXTAPPOINTMENTTIME = ADDTIME(lo_ADJUSTMENTTIME,'00:20:00');
end if;
update tds_tokengeneration set ADJUSTMENTTIME=lo_ADJUSTMENTTIME,
NEXTAPPOINTMENTTIME=lo_NEXTAPPOINTMENTTIME,
SMSSTATUS=lo_SMSSTATUS
where TOKENNUMBER=lo_TOKENNUMBER and TOKENDATE=cdate and SERIALNO=lo_SERIALNO;
end if;
end loop time_loop;
close mycur;
end loop bt_loop;
close btcountcur;
END$$
DELIMITER ;
.but when i executing this program i'm getting below error
(0 row(s)affected)
(0 ms taken)
Error Code : 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Declare mycur cursor for
select TOKENNUMBER,APPOINTMENTTIME,ADJ' at line 33
(0 ms taken)
Declarations must follow a certain order.
It is not allowed to declare a cursor or an event handler in the middle of your procedure. Yes, the error message is misleading to say the least. You must declare the mycur cursor at the beginning of a BEGIN ... END block.
You could either move the second cursor declaration to the beginning of your procedure, or nest a BEGIN ... END block at an appropriate location.
Related
I am new to mysql store procedure. I want my store procedure to check date value in Field date and compare to current date. If current date is bigger than date value in table, I want to update value in field status_number to '0'.
Here is my query :
DELIMITER $$
DROP PROCEDURE IF EXISTS check_status$$
CREATE PROCEDURE check_status()
BEGIN
DECLARE dd DATE;
DECLARE bDone INT;
DECLARE Count INT;
DEClARE my_status CURSOR FOR SELECT dates FROM t_date;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN my_status;
SET bDone = 0;
REPEAT
FETCH my_status INTO dd;
IF (dd < DATE(NOW()))
UPDATE t_date SET (status_number) VALUES (1);
END IF;
UNTIL bDone END REPEAT;
CLOSE my_status;
END$$
DELIMITER ;
Error message :
Thank for answering.
DELIMITER $$
DROP PROCEDURE IF EXISTS check_status$$
CREATE PROCEDURE check_status()
BEGIN
DECLARE dd DATE;
DECLARE bDone INT;
DECLARE Count INT;
DEClARE my_status CURSOR FOR SELECT dates FROM t_date;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN my_status;
SET bDone = 0;
REPEAT
FETCH my_status INTO dd;
IF (dd < DATE(NOW()))
-- UPDATE t_date SET (status_number) VALUES (1);
UPDATE t_date SET status_number = 1;
END IF;
UNTIL bDone END REPEAT;
CLOSE my_status;
END$$
DELIMITER ;
Check it. its tested on mssql. I try to convert it for mysql but not tested on mysql but i hope it will works.
DELIMITER //
CREATE PROCEDURE check_status()
BEGIN
DECLARE NOT_FOUND INT DEFAULT 0;
DECLARE v_dd DATE;
-- DECLARE #bDone INT;
-- DECLARE #Count INT;
DECLARE v_name VARCHAR(50); -- database name
DECLARE v_path VARCHAR(256); -- path for backup files
DECLARE v_fileName VARCHAR(256); -- filename for backup
DECLARE v_fileDate VARCHAR(20); -- used for file name
DECLARE db_cursor CURSOR FOR
SELECTdates INTO v_dd
FROM t_date
OPEN
DECLARE CONTINUE HANDLER FOR NOT FOUND SET NOT_FOUND = 1;db_cursor
-- SET #bDone = 0;
FETCH NEXT FROM; db_cursor INTO v_dd
WHILE NOT_FOUND = 0
DO
IF (v_dd < cast (Now() as date) )
Then
UPDATE t_date SET status_number = 1;
END IF;
FETCH NEXT FROM; db_cursor INTO v_dd
END WHILE;
CLOSE db_cursor;
END;
//
DELIMITER ;
Getting error on following trigger:
DELIMITER $$
CREATE TRIGGER limit_refferals AFTER INSERT
ON wpmr_aff_referrals
FOR EACH ROW
BEGIN
DECLARE vCNT INT;
DECLARE USERID varchar(50);
DECLARE AFFILIATEID varchar(50);
DECLARE i INTEGER;
DECLARE curs1 CURSOR FOR SELECT USER_ID,affiliate_id
FROM `wpmr_aff_referrals` WHERE affiliate_id=:NEW.affiliate_id;
SELECT CUSTOMERLEVEL(:NEW.affiliate_id) INTO vCNT;
IF (vCNT>=3)
set i=1;
OPEN curs1;
read_loop: LOOP
FETCH curs1 INTO USERID,AFFILIATEID;
SELECT CUSTOMERLEVEL(:NEW.affiliate_id) INTO vCNT;
IF (vCNT>=3)
set i=i+1;
ELSE
set new.affiliate_id= AFFILIATEID;
END IF;
END LOOP read_loop;
CLOSE curs1;
END IF;
END$$
DELIMITER ;
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near ':NEW.affiliate_id; SELECT CUSTOMERLEVEL(:NEW.affiliate_id) INTO
vCNT;
IF (vC' at line 10
DELIMITER $$
CREATE TRIGGER limit_refferals BEFORE INSERT
ON wpmr_aff_referrals
FOR EACH ROW
BEGIN
DECLARE vCNT INT;
DECLARE USERID varchar(50);
DECLARE AFFILIATEID varchar(50);
DECLARE i INTEGER;
DECLARE curs1 CURSOR FOR
SELECT USER_ID,affiliate_id
FROM `wpmr_aff_referrals` WHERE affiliate_id=NEW.affiliate_id;
SELECT CUSTOMERLEVEL(NEW.affiliate_id) INTO vCNT;
IF (vCNT >=3) THEN /*<------------Made changes at this line*/
set i=1;
OPEN curs1;
read_loop : LOOP
FETCH curs1 INTO USERID,AFFILIATEID;
SELECT CUSTOMERLEVEL(NEW.affiliate_id) INTO vCNT;
IF (vCNT>=3) THEN /*<------------Made changes at this line*/
set i=i+1;
ELSE
set new.affiliate_id= AFFILIATEID;
END IF;
END LOOP read_loop;
CLOSE curs1;
END IF;
END$$
DELIMITER ;
Try above code.
One more thing you can't use NEW row for BEFORE UPDATE TRIGGER.So i had made changes to AFTER UPDATE TRIGGER.
We don't need : for NEW and OLD value,you can directly check that value using NEW.VAL and OLD.VAL.
Also whenever you use IF IN TRIGGER,PROCEDURE and FUNCTION put THEN and then write you logic
Hope this will help you.
Remove the ":" to pass the parameter NEW.affiliate_id to the CUSTOMERLEVEL function like this:
SELECT CUSTOMERLEVEL(NEW.affiliate_id) INTO vCNT
I am reading an article on stored procedures and this is the code:
delimiter //
create procedure largest_order(out largest_id int)
begin
declare this_id int;
declare this_amount float;
declare l_amount float default 0.0;
declare l_id int;
declare done int default 0;
declare continue handler for sqlstate '02000' set done = 1;
declare c1 cursor for select orderid, amount from orders;
open c1;
repeat
fetch c1 into this_id, this_amount;
if not done then
if this_amount > l_amount then
set l_amount=this_amount;
set l_id=this_id;
end if;
end if;
until done end repeat;
close c1;
set largest_id=l_id;
end
//
delimiter ;
I am using a simple database named "mydatabase". After running the above code it gives me this error: ERROR 1338 (42000): Cursor declaration after handler declaration
What is wrong and how can I fix it?
This is my first time working with stored procedures.
Per MySql docs:
Cursor declarations must appear before handler declarations and after
variable and condition declarations.
So I updated the code as follows:
delimiter //
create procedure largest_order(out largest_id int)
begin
declare this_id int;
declare this_amount float;
declare l_amount float default 0.0;
declare l_id int;
-- 1. cursor finished/done variable comes first
declare done int default 0;
-- 2. the curser declaration and select
declare c1 cursor for select orderid, amount from orders;
-- 3. the continue handler is defined last
declare continue handler for sqlstate '02000' set done = 1;
open c1;
repeat
fetch c1 into this_id, this_amount;
if not done then
if this_amount > l_amount then
set l_amount=this_amount;
set l_id=this_id;
end if;
end if;
until done end repeat;
close c1;
set largest_id=l_id;
end
//
delimiter ;
And now works fine.
What is wrong in the syntax of the below stored procedure in MySQL ?
CREATE PROCEDURE curdemo()
BEGIN
DECLARE #isbn varchar(17)
DECLARE #count int
DECLARE #price float(6,2)
DECLARE #totalbookpriceValue float(6,2)
DECLARE totalbookprice CURSOR
STATIC FOR
(SELECT ISBN,COUNT(ISBN) FROM applieddb.cart c GROUP BY ISBN)
OPEN totalbookprice
IF ##CURSOR_ROWS > 0 BEGIN
FETCH NEXT FROM cur_emp INTO #isbn,#count
WHILE ##Fetch_status = 0
SELECT ISBN,PRICE FROM book INTO #price WHERE ISBN = #isbn
PRINT 'Total Book Price is' + #price * #count
FETCH NEXT FROM cur_emp INTO #isbn,#count
END
END
CLOSE totalbookprice
DEALLOCATE totalbookprice
SET NOCOUNT OFF
END
ERROR Message:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '#isbn varchar(17) DECLARE #count int DECLARE #price float(6,2) DECLARE #totalboo' at line 3
Changing the mysql query to the below also did not help and gave the following error:
DECLARE for local (without #) or SET for session (with #)
***The solution to the above problem is as below:***
CREATE DEFINER=`root`#`localhost` PROCEDURE `calculateTotalPrice`()
BEGIN
DECLARE done INT default 0;
DECLARE _isbn varchar(17);
DECLARE _count int;
DECLARE _price float(6,2);
DECLARE loop_cntr INT DEFAULT 0;
DECLARE _totalbookpriceValue float(6,2);
DECLARE totalbookprice CURSOR FOR SELECT ISBN,COUNT(ISBN) FROM applieddb.cart c GROUP BY ISBN;
DECLARE CONTINUE HANDLER FOR NOT FOUND set done= TRUE;
OPEN totalbookprice;
the_loop: LOOP
FETCH totalbookprice into _isbn,_count;
SET _price= (SELECT b.price from book b where b.ISBN = _isbn);
SET _totalbookpriceValue= _price*_count;
SELECT _totalbookpriceValue;
IF done THEN
CLOSE totalbookprice;
LEAVE the_loop;
END IF;
-- count the number of times looped
SET loop_cntr = loop_cntr + 1;
END LOOP the_loop;
END
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?