MySQL stored procedure causes error - mysql

Can someone kindly tell me where I'm wrong ?
This procedure returns an error near
#recuperato = #recuperato - saldofattura;
I mistake to update the variable #recuperato?
Thanks to all
DELIMITER //
DROP PROCEDURE IF EXISTS fatture_lettere_retail//
CREATE PROCEDURE fatture_lettere_retail (idcontratto INT(11))
BEGIN
DECLARE finito INT default 0;
DECLARE idfattura INT default 0;
DECLARE saldofattura DECIMAL(10,2);
DECLARE cur1 CURSOR FOR SELECT idfattura,saldofattura FROM fatture_lettere_isa;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET finito = 1;
SET #recuperato=(SELECT SUM(valorea)-SUM(valorer) FROM ImportiContratto WHERE idcontratto=idcontratto AND idimporto=1);
ciclo: LOOP
SET finito = 0;
FETCH cur1 INTO idfattura,saldofattura;
IF finito THEN
LEAVE ciclo;
END IF;
IF (#recuperato-saldofattura>=0) THEN
#recuperato = #recuperato-saldofattura;
DELETE FROM fatture_lettere_isa WHERE idfattura=idfattura;
ELSE
UPDATE fatture_lettere_isa SET saldofattura=saldofattura-#recuperato;
LEAVE ciclo;
END IF;
END LOOP ciclo;
CLOSE cur1;
END; //
DELIMITER;

Add the SET keyword at the beginning of the row in question:
SET #recuperato = #recuperato-saldofattura;

You have to write SET keyword to assign value to variable "#recuperato" as follow:
SET #recuperato = #recuperato-saldofattura;

Related

MySQL cursor does not loop only return the first record

I am trying a sample SP. This SP does not loop. Trying to figure what where the problem is. Any help is appreciated
DELIMITER $$
USE `DB`$$
DROP PROCEDURE IF EXISTS `build_email_list`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `build_email_list`()
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_email VARCHAR(100) DEFAULT "";
-- declare cursor for employee email
DECLARE email_cursor CURSOR FOR SELECT `email` FROM `people`;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN email_cursor;
get_email: LOOP
FETCH email_cursor
INTO v_email;
IF v_finished = 1 THEN
LEAVE get_email;
END IF;
-- print list
SELECT v_email;
END LOOP get_email;
CLOSE email_cursor;
END$$
DELIMITER ;

mysql table trigger throughs error

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

MySQL cursor fetch NULL

Why both my variables output NULL? SELECT part of the cursor is working properly.
CREATE PROCEDURE p2()
BEGIN
# Account table
DECLARE accountid INT;
DECLARE accountname VARCHAR(1000);
# 1. cursor finished/done variable comes first
DECLARE done INT DEFAULT 0;
# 2. the curser declaration and select
DECLARE c_account_id_name CURSOR FOR SELECT
accountid,
accountname
FROM temp.test;
# 3. the continue handler is defined last
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
OPEN c_account_id_name;
SET accountid = 0;
SET accountname = '';
read_loop: LOOP
FETCH c_account_id_name
INTO accountid, accountname;
IF done
THEN
LEAVE read_loop;
END IF;
SELECT accountname;
END LOOP;
END;
Variable and select attribute in cursor can't be the same...it's a MySQL bug.
This will work
DROP PROCEDURE IF EXISTS p2;
DELIMITER $$
CREATE PROCEDURE p2()
BEGIN
# Account table
DECLARE v_accountidsome INT; #pay attention
DECLARE v_accountnameelst VARCHAR(1000); #pay attention
# 1. cursor finished/done variable comes first
DECLARE v_done INT DEFAULT FALSE;
# 2. the cursor declaration and select
DECLARE c_account_id_name CURSOR FOR SELECT
accountid, #pay attention
accountname #pay attention
FROM temp.test;
# 3. the continue handler is defined last
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET v_done = TRUE;
OPEN c_account_id_name;
read_loop: LOOP
FETCH c_account_id_name
INTO v_accountidsome, v_accountnameelst;
IF v_done
THEN
LEAVE read_loop;
END IF;
SELECT v_accountidsome;
SELECT v_accountnameelst;
END LOOP;
CLOSE c_account_id_name;
END $$
DELIMITER ;
CALL p2();
Find more here

MySql Procedure not returning value

I'm unable to get the result of OUT variable in this code, am I doing wrong something? can anyone help?
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE cid INT(10);
DECLARE cuserid VARCHAR(50);
DECLARE cur1 CURSOR FOR SELECT id,username FROM tblcustomer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO cid,cuserid;
IF done THEN
LEAVE read_loop;
END IF;
SET customers_list = CONCAT(customers_list,cid,':',cuserid,',');
END LOOP;
CLOSE cur1;
END
The procedure prototype is missing from your snippet, but assuming the below:
CREATE PROCEDURE foo(OUT customers_list VARCHAR(100))
BEGIN
...
SET customers_list = 'foo-list';
END ;
This is how you would retreive your "return value":
CALL foo(#var);
SELECT #var; -- outputs "foo-list"
Strictly speaking, a procedure has no "return value". A function has:
CREATE FUNCTION bar() RETURNS VARCHAR(100)
BEGIN
...
RETURN 'bar-list';
END ;
SELECT bar(); -- outputs "bar-list";

Using for loop in MySql data set

How to use for loop in MySQL data set ?
FOR x IN (SELECT column FROM table_name WHERE column_2 = input_val)
LOOP
sum_total := sum_total + x.column ;
END LOOP;
This is an example how I used to loop data set in oracle.
How can this be achieved in MySql ?
How about not looping at all. It's SQL after all.
SELECT SUM(`column`) total
FROM table_name
WHERE column_2 = <input_val>
Otherwise use CURSOR
Now, equivalent loop using CURSOR will look like
DELIMITER $$
CREATE PROCEDURE sp_loop(IN input_val INT)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE sum_current, sum_total INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT column1 FROM table_name WHERE column2 = input_val;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO sum_current;
IF done THEN
LEAVE read_loop;
END IF;
SET sum_total = sum_total + sum_current;
END LOOP;
CLOSE cur1;
SELECT sum_total;
END$$
DELIMITER ;
Here is SQLFiddle
DROP PROCEDURE IF EXISTS `foo`.`usp_cursor_example`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `foo`.`usp_cursor_example`(
IN name_in VARCHAR(255)
)
READS SQL DATA
BEGIN
DECLARE name_val VARCHAR(255);
DECLARE status_update_val VARCHAR(255);
-- Declare variables used just for cursor and loop control
DECLARE no_more_rows BOOLEAN;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
-- Declare the cursor
DECLARE friends_cur CURSOR FOR
SELECT
name
, status_update
FROM foo.friend_status
WHERE name = name_in;
-- Declare 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = TRUE;
OPEN friends_cur;
select FOUND_ROWS() into num_rows;
the_loop: LOOP
FETCH friends_cur
INTO name_val
, status_update_val;
IF no_more_rows THEN
CLOSE friends_cur;
LEAVE the_loop;
END IF;
select name_val, status_update_val;
-- count the number of times looped
SET loop_cntr = loop_cntr + 1;
END LOOP the_loop;
-- 'print' the output so we can see they are the same
select num_rows, loop_cntr;
END
DELIMITER ;