how to declare & set cursor in MYSQL STORED PROCEDURE? - mysql

I am trying to use CURSOR inside mysql stored procedure... I am getting challenge while declaring the cursor... I error is **ERROR 1064 (42000): 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 ';
SELECT count(*) INTO countitem from TBL_SHOPPING_CART_ITEM
SELECT Produ' at line 8
**
Please help me to solve this issue... Thanks in advance.. my code is like below,
delimiter //
CREATE PROCEDURE placeOrder(IN cartId INT)
BEGIN
DECLARE countitem INT;
DECLARE productId INT;
DECLARE cartId INT;
DECLARE itemDicountAmt INT;
DECLARE itemCursor CURSOR;
SET countitem = SELECT count(*) from TBL_SHOPPING_CART_ITEM
SET itemCursor = SELECT ProductId, Quantity FROM TBL_SHOPPING_CART_ITEM
OPEN itemCursor
WHILE countitem > 0
BEGIN
FETCH itemCursor into productId, cartId;
itemDicountAmt = calculateNetItemStandardDiscountAmount(productId, cartId);
insert into debugtable select concat('item discount amount', itemDicountAmt);
SET countitem = countitem - 1;
END
CLOSE itemCursor
DEALLOCATE itemCursor
END//
delimiter ;

Don't worry, this isn't a bug.
The DECLARE clause is used to tell your machine that a local variable exists. The operations are made after the declarations, by aknowledging the existing, declared local variables.
So in your case, you tried to add a new declaration of variable after the machine started calculating, which isn't possible in MySQL. You'll have to find another way to use your last variable.
To assign a new content to a variable, first use DECLARE to create your variable first, then use SET as an assignment to the declared variable. I'll leave this link right here so you can get to know how to use it.

Related

I dont't understand why im getting syntax error on my code below. Can anyone help me?

DELIMITER ##
create trigger tra_Price after update on assets_cdn_charge for each row
begin
declare res int;
declare ids int;
declare idq int;
declare idt int;
set res = (select price from assets_cdn_charge where price = new.price);
set ids = (select id from assets_cdn_charge where price = new.price);
DECLARE cur CURSOR FOR SELECT id FROM assets_cdn_composite WHERE cdn_charge_id = ids;
open cur;
ins_loop:LOOP
fetch cur into idq;
declare curs cursor for select id from assets_cdn_traffic where domain_name_id = idq;
open curs;
ins1_loop:LOOP
fetch curs into idt;
update assets_cdn_traffic set cost = traffic * res where domain_namd_id = idt;
end LOOP;
close curs;
end LOOP;
close cur;
END; ##
when I run this code,I had get this error:
ERROR 1064 (42000): 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 cur CURSOR FOR SELECT id FROM
assets_cdn_composite WHERE cdn_charge_id =' at line 9
Probably because:
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
...so that line should likely be moved before the two set statements above that point.
I believe that you're going to have other trouble if that fixes that error, because I don't know what you expect that query to retrieve as idq is declared before that point, but is not set to any value?
=====
UPDATE:
Below is an example from a previous comment about the possibility to eliminate cursors altogether. Try this:
BEGIN
UPDATE assets_cdn_traffic
JOIN assets_cdn_composite ON assets_cdn_traffic.domain_name_id = assets_cdn_composite.cdn_charge_id
JOIN assets_cdn_charge ON assets_cdn_charge.id = assets_cdn_composite.cdn_charge_id
SET cost = traffic * NEW.price
WHERE assets_cdn_charge.id = NEW.id
END
However, I would try the update query separately before using in the trigger to make sure that it works as expected. Replace the NEW.price and the NEW.id with test values to verify the handling.

Update statement in stored procedure is not working

I have a stored procedure in Mysql database like this:
DELIMITER $$
USE `vboard_75`$$
DROP PROCEDURE IF EXISTS `sp_LongWaitCall`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_LongWaitCall`()
BEGIN
UPDATE cdr SET cdr.CallStatus='DISCONNECTED',cdr.EndTime=NOW() WHERE cdr.CallStatus='RINGINGIN'
AND MINUTE(DATEDIFF(cdr.StartTime,NOW())) >=7;
DECLARE _StatVal FLOAT;
DECLARE _DevID INT;
DECLARE Record_Fetch INT DEFAULT 0;
DECLARE crsr_Board CURSOR FOR
SELECT IFNULL(MAX(SECOND(DATEDIFF(CDR.StartTime, IFNULL(CDR.EndTime, NOW())))), 0) AS LRT,vw_Boards_Ext.boardid
FROM vw_Boards_Ext RIGHT OUTER JOIN
boards ON vw_Boards_Ext.boardid = boards.boardid LEFT OUTER JOIN
CDR ON vw_Boards_Ext.Ext = CDR.DDI AND
STR_TO_DATE(CONCAT(boards.ResetDate,' ',boards.ResetTime),'%m/%d/%Y %H:%i') < CDR.timestamp
AND CDR.CallStatus='RINGINGIN'
GROUP BY vw_Boards_Ext.boardid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Record_Fetch = 1;
OPEN crsr_Board;
FETCH crsr_Board INTO _StatVal, _DevID;
WHILE Record_Fetch = 0 DO
UPDATE stat_values AS sv SET sv.StatValue = _StatVal,sv.timestamp= NOW()
WHERE sv.itemId = _DevID AND sv.itemType = 'boards' AND sv.StatId = 3;
FETCH crsr_Board INTO _StatVal, _DevID;
END WHILE;
CLOSE crsr_Board;
DEALLOCATE PREPARE crsr_Board;
END$$
DELIMITER ;
Error:
Query: CREATE DEFINER=root#localhost PROCEDURE sp_LongWaitCall() BEGIN update cdr set cdr.CallStatus='DISCONNECTED',cdr.EndTime=n...
Error Code: 1064
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 'DECLARE _StatVal FLOAT;
DECLARE _DevID INT;
DECLARE Record_Fetch INT DEFAULT 0' at line 8
Execution Time : 0 sec
Transfer Time : 0 sec
Total Time : 0.001 sec
This documentation refers to having the DECLARE statements at the top and also before the creation of any CURSORS and HANDLERS, which you are following but not at the beginning of the BEGIN... END block.
This documentation clarifies the question that OP had posted!
It is mandatory to have your declarations at the begin of your BEGIN... END block, but not under an UPDATE statement.
Additional reference to a similar issue can be found on this question, even which refers to the same solution.
Hope this helps!

Error with MySQL, DECLARE

I am using MySQL v5.0.92 and I'm trying to import some data, but I get an error on declare my variables.
BEGIN
DECLARE flag INT;
DECLARE id INT;
while flag=0 begin
SET id=(SELECT top 1 user_id
FROM ac_user_info WHERE user_id>#id order by user_id)
INSERT INTO cuddleew_database1.cewp_usermeta(user_id,meta_key,meta_value)
SELECT id,'first_name',first_name
FROM cuddleew_backup.ac_user_info WHERE user_id=#id
INSERT INTO cuddleew_database1.cewp_usermeta(user_id,meta_key,meta_value)
SELECT id,'last_name',last_name
FROM cuddleew_backup.ac_user_info WHERE user_id=#id
SET flag=(select case #id when(SELECT MAX(user_id)
FROM cuddleew_bakup.ac_user_info) then 1
else 0
END CASE)
END WHILE
END
In MySQL console i get this:
BEGIN DECLARE flag INT;
#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 flag INT' at line 2.
Can you help me with this and tell me what's wrong. Thanks in advance.
You have to change your delimiter first, so the ; doesn't tell MySQL that this command is over.
DELIMITER $$
[your code here]
END $$
DELIMITER ;

MySQL: Solve my MySQL Cursor Error:1064

DROP TRIGGER IF EXISTS `ACTUALIZAR_LOTE_DETALLE`;
DELIMITER //
CREATE TRIGGER `ACTUALIZAR_LOTE_DETALLE` AFTER INSERT ON `detalle_envio`
FOR EACH ROW BEGIN
DECLARE ID_INVENTARIO_IN INT;
DECLARE ID_LOTE_DETALLE_MIN INT;
DECLARE CANTIDAD_A_COMPARAR INT;
DECLARE CANTIDAD_A_RESTAR INT;
SET CANTIDAD_A_RESTAR = new.cantidad_enviado;
SET ID_INVENTARIO_IN = (Select id_inventario from detalle_requisicion WHERE id_detalle_requisicion = new.id_detalle_requisicion);
DECLARE cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inventario = ID_INVENTARIO_IN AND cantidad > 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = 1;
OPEN cur_id;
read_loop: LOOP
FETCH cur_id INTO LOTE_DETALLE_IDS;
SET CANTIDAD_A_COMPARAR = select cantidad from lote_detalle where id_lote_detalle = LOTE_DETALLE_IDS;
IF CANTIDAD_A_RESTAR > CANTIDAD_A_COMPARAR THEN
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_COMPARAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
SET CANTIDAD_A_RESTAR = CANTIDAD_A_RESTAR - CANTIDAD_A_COMPARAR;
ELSE
UPDATE `lote_detalle` SET cantidad=cantidad-CANTIDAD_A_RESTAR WHERE id_lote_detalle = LOTE_DETALLE_IDS;
LEAVE read_loop;
END IF;
IF DONE = 1 THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
CLOSE cur_id;
END
//
DELIMITER ;
Is anything in the cursor?
the query or something?
Is anything in the Syntax?
Cause i have based this Trigger from the syntax of the MySQL Forums
This is the Error:
#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 cur_id CURSOR FOR SELECT id_lote_detalle from lote_detalle WHERE id_inve' at line 9
There are at least following issues with your code:
All declarations should come before any statements (SET in your case). That's what is causing your immediate error.
You didn't declare DONE variable
You didn't declare LOTE_DETALLE_IDS variable, but you declared ID_LOTE_DETALLE_MIN which you didn't use. Perhaps you should rename ID_LOTE_DETALLE_MIN to LOTE_DETALLE_IDS then.
Since declarations go first you have to re-write your cursor definition (e.g. with subquery) because ID_INVENTARIO_IN variable isn't initialized yet
Your whole declaration section can be re-written in a following manner
-- declaration of variables of the same type can be combined
DECLARE ID_INVENTARIO_IN,
LOTE_DETALLE_IDS,
CANTIDAD_A_COMPARARINT,
CANTIDAD_A_RESTAR,
DONE INT;
DECLARE cur_id CURSOR FOR ...
DECLARE CONTINUE HANDLER ...
-- initialize variables
SET ...
Now, I believe your trigger most likely can be re-written with just update statement(s). You can get help with it if you explain in plain words what you're trying to achieve and provide exact table schemas and sample data.

can't create mysql stored procedure

I'm a bit of a noob when it comes to stored procedures in general, but I'm trying to write the following
Create procedure clone_perms
as
declare #new_id varchar(30), #old_id varchar(30)
declare get_perms cursor for select userspermsUserid, userspermsPermission from users_permissions where userspermsUserid=#old_id
declare #perms varchar(30), #on_off boolean
FETCH get_perms into #perms, #on_off
while(##sqlstatus=0)
BEGIN
if exists ( select 1 from permissions where userspermsUserid=#new_id and userspermsPermID=#perm )
BEGIN
update permissions set userspermsPermission=#on_off where userspermsUserid=#new_id and userspermsPermID=#perm
END
else
BEGIN
insert permissions (userspermsUserID, userspermsPermID, userspermsPermission) values (#new_id, #perms, #on_off)
END
FETCH get_perms into #perms, #on_off
END
CLOSE get_perms
DEALLOCATE CURSOR get_perms
end
. I get the following error when trying to create it:
/* SQL Error (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 'as declare #new_id varchar(30) declare #old_id varchar(30) declare get_perm' at line 2 */
. Does anyone know what I need to do to make this work?
You need to have BEGIN tag after CREATE PROCEDURE clone_perms and not AS
don't use an # to start local (declared) variable names, that's only for user variables you create with the
SET #varname=value;
statement. you'll also need to terminate your statements with a semicolon. that's the cause of the latest error, there's no ; after your first declare statement.