Printing out multiple rows in stored procedure - mysql

I want to pass in an int value and get back a list of short passwords that are less than this int. I have had trouble modifying the MySQL cursors example: http://dev.mysql.com/doc/refman/5.0/en/cursors.html. I want to print out the rows with short passwords but any time the result has more than one row PhpMyAdmin just displays "Processing request" indefinitely. What am I doing wrong? Its ruining my Saturday productivity!
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `ShortPasswd`(IN `passwordLength` TINYINT)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a INT;
DECLARE b VARCHAR(255);
DECLARE cur1 CURSOR FOR SELECT UID, Password
FROM authentication WHERE CHARACTER_length(Password) < passwordLength;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO a, b;
IF done THEN
LEAVE read_loop;
END IF;
SELECT b;
END LOOP;
CLOSE cur1;
END
$$
DELIMITER ;

DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `ShortPasswd`(IN `passwordLength` TINYINT)
BEGIN
SELECT UID, Password
FROM authentication WHERE CHARACTER_length(Password) > passwordLength;
END
$$
DELIMITER ;
You will get rows UID, password directly. as you get from a query when you
call ShortPasswd;

I suggest to modify these lines:
...
DECLARE FINISHED BOOLEAN DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
...
IF done THEN
CLOSE cur1;
LEAVE read_loop;
END IF;
...
END LOOP read_loop;
I use the 0/1 instead of FALSE/TRUE, and close the cursor before leave the LOOP.

Related

Nested Cursor Into Mysql

I am creating cursor within cursor and first cursor getting unique value and second cursor is generating details number of rows. I found second cursor is running one time and not populating rows against every row id. Please guide
DELIMITER $$
USE `dum_data`$$
DROP PROCEDURE IF EXISTS `sp_process_gen`$$
CREATE DEFINER=`test`#`%` PROCEDURE `sp_process_gen`()
BEGIN
DECLARE cur1_done,cur2_done INT DEFAULT 0;
DECLARE v_thread_id, v_id,v_tab,v_event_time INT;
DECLARE v_stime,v_etime DATETIME;
-- declaring cursor
DECLARE cur1 CURSOR FOR
SELECT thread_id
FROM general_log
-- WHERE thread_id in (306710429,306711335)
GROUP BY thread_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET cur1_done = 1;
OPEN cur1;
cur1_loop: LOOP
FETCH cur1 INTO v_thread_id;
-- INSERT INTO aa VALUES(NULL,v_thread_id,NULL,NULL);
block2: BEGIN
DECLARE cur2 CURSOR FOR
SELECT id , event_time
FROM general_log
WHERE thread_id = v_thread_id
ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET cur2_done = 1;
OPEN cur2;
cur2_loop: LOOP
FETCH cur2 INTO v_id,v_stime;
IF cur2_done THEN
-- set cur1_done = 0;
CLOSE cur2;
LEAVE cur2_loop;
END IF;
-- INSERT INTO aa VALUES(v_id,v_thread_id,v_stime,v_stime);
INSERT INTO aa(thread_id) VALUES(v_thread_id);
-- FETCH cur2 INTO v_id,v_stime;
END LOOP cur2_loop;
END block2;
IF cur1_done THEN
CLOSE cur1;
LEAVE cur1_loop;
END IF;
INSERT INTO aa(thread_id) VALUES(999999);
-- FETCH cur1 INTO v_thread_id;
END LOOP cur1_loop;
-- CLOSE cur;
END$$
DELIMITER ;
I suspect your problem is the two CONTINUE HANDLER FOR NOT FOUND structures.
The second cursor will get it's first NOT FOUND at the end its loop, trigger both handlers... causing both loops to exit.
The way around this is to have a second stored procedure that contains the inner loop, and call that procedure from the outer loop. That way your handlers are in separate contexts.

MySQL: Column is empty in an insert log

I have this stored procedure in mysql:
DELIMITER $$
CREATE PROCEDURE createCompany ()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE company varchar(5000) DEFAULT "";
DEClARE cur CURSOR FOR SELECT company FROM companies;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1
OPEN cur;
getCompany: LOOP
FETCH cur INTO company;
IF finished = 1 THEN
LEAVE getCompany;
END IF;
call LOG(company);
END LOOP getCompany;
CLOSE cur;
END$$
DELIMITER ;
LOG procedure is:
DELIMITER $$
CREATE PROCEDURE `LOG`(IN message varchar(5000))
BEGIN
insert into tmplog (log) values (message);
END$$
DELIMITER ;
I have a temporal table called tmplog with two fields: date and log (varchar(5000))
When I call createCompany I get the next result:
the log column is empty... what is wrong?
Having variables with the same name as columns is very dangerous. Try this:
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_company varchar(5000) DEFAULT "";
DEClARE cur CURSOR FOR SELECT c.company FROM companies c;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1
OPEN cur;
getCompany: LOOP
FETCH cur INTO v_company;
IF v_finished = 1 THEN
LEAVE getCompany;
END IF;
call LOG(v_company);
END LOOP getCompany;
CLOSE cur;
END$$
DELIMITER ;

Get Columns Single Record in Stored Procedure Mysql

I have my procedure and is working, but my question is the following,
with the cursor is working correctly, but before the cursor I need a Single Record with several columns, I donĀ“t know if I need another cursor just for one record.
Which would be the right way to get the columns of that single row without a cursor.
The query to execute is:
'SELECT id,anio,fec_iniciointeres FROM mytable WHERE id=3 '
DELIMITER $$
DROP PROCEDURE IF EXISTS db.cal_intereses$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `cal_intereses`()
BEGIN
DECLARE factura_id INT UNSIGNED;
DECLARE val_avaluo DECIMAL(16,2);
DECLARE fec_actual DATE;
DECLARE done INT;
DECLARE cur CURSOR FOR SELECT fac_facturas.id AS factura_id, fac_facturas.val_avaluo FROM fac_facturas WHERE fac_facturas.vigencia_id<=26 AND fac_facturas.estado=1 AND fac_facturas.val_avaluo>0 LIMIT 10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
SET fec_actual=(SELECT CURDATE());
SET done = 0;
OPEN cur;
ciclo: LOOP
FETCH cur INTO factura_id,val_avaluo;
IF done=1 THEN LEAVE ciclo; END IF;
DELETE FROM val_interesaux;
IF fec_actual>='2006-07-29' THEN
INSERT INTO val_interesaux(factura_id,fec_inicio) VALUES(factura_id,fec_actual);
END IF;
END LOOP ciclo;
CLOSE cur;
END$$
DELIMITER ;

Cursor incorrect integer value error

I am trying to make my first cursor in MySQL and I am receiving an error. It says incorrect integer value. I was thinking this would grab the value in row one from column customer_Id, and store it into the IdValue variable. How do I code this correctly and fix this error?
DELIMITER $$
CREATE PROCEDURE CursorProcedure()
BEGIN
DECLARE IdValue int;
DECLARE myCursor CURSOR FOR
SELECT customer_Id FROM customers;
OPEN myCursor;
FETCH myCursor INTO IdValue;
CLOSE myCursor;
SELECT IdValue;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS CursorProcedure;
DELIMITER $$
CREATE PROCEDURE CursorProcedure()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE IdValue int;
DECLARE myCursor CURSOR FOR SELECT customer_Id FROM customers;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN myCursor;
read_loop: LOOP
FETCH myCursor INTO IdValue;
IF done THEN
LEAVE read_loop;
END IF;
--
-- YOU ARE IN YOUR READ LOOP
-- DO SOMETHING WITH IT HERE
--
END LOOP;
CLOSE myCursor;
END$$
DELIMITER ;
But in the "do something with it here", don't do a SELECT on it because it will generate multiple result sets. Do something meaningful.
Manual page on Cursors.
As an aside, cursors are rarely your friends. They are extremely slow. Use them in dire emergencies only.

What is the right method to reuse a cursor inside a mysql stored procedured?

What is the right method to reuse a cursor inside a mysql stored procedure?
We're doing it like below, and It just does not look correct. Does anyone know whats the right method to do this?
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `fred`$$
CREATE DEFINER=`root`#`windows7.home` PROCEDURE `fred`()
BEGIN
DECLARE X INT;
DECLARE done INT DEFAULT FALSE;
DECLARE myType INT;
DECLARE cur1 CURSOR FOR SELECT val FROM checkval;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET X = 10;
WHILE X >= 2 DO
##############
OPEN cur1;
FETCH cur1 INTO myType;
read_loop: LOOP
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO myType VALUES (myType);
FETCH cur1 INTO myType;
END LOOP read_loop;
CLOSE cur1;
SET X = X-1;
SET done=FALSE;
##################
END WHILE;
END$$
DELIMITER ;
Heres the question that started it:
While loop in stored procedure loops only twice instead of 8 times