I'm trying to use input parameters of a stored procedure within a cursor of the procedure.
Calling the procedure as follows results in an Error
-- -role- -table- -cond-
CALL grantRoleToUsersFromWhere('Student', 'studenten', true);
Error Code: 1146. Table 'uni4.utable' doesn't exist
This tells me that the parameter 'userTable' was not written to the variable 'uTable' OR 'uTable' is not recognized as a variable at all by the cursor Statement.
I tried different approaches storing / using the parameters. e.g. use them directly or store them in a Variable with a SET statement. However, if I try to use SET uTable=userTable; before the cursor declaration, MySQL WorkBench won't accept the Procedure declaration.
I spent quite some time on this but I think I'm missing an important yet simple part :-)
DROP PROCEDURE IF EXISTS grantRoleToUsersFromWhere;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE grantRoleToUsersFromWhere(IN grantRole VARCHAR(30), IN userTable VARCHAR(30), IN addCondition VARCHAR(50))
BEGIN
DECLARE workUser VARCHAR(30) default '';
DECLARE gRole VARCHAR(30) default grantRole;
DECLARE uTable VARCHAR(30) default userTable;
DECLARE aCond VARCHAR(50) default addCondition;
DECLARE cur1 CURSOR FOR SELECT Name FROM uTable WHERE aCond;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO workUser;
GRANT gRole TO workUser;
END LOOP;
CLOSE cur1;
END $$
DELIMITER ;
Create dynamic cursors directly is not possible. You can however use VIEW's to achieve the same thing. See sample.
CREATE PROCEDURE p1 (select_statement VARCHAR(255))
BEGIN
DECLARE v1,v2 VARCHAR(255);
DECLARE c CURSOR FOR SELECT * FROM t;
SET #v = CONCAT('create temporary table t as ',select_statement);
PREPARE stmt1 FROM #v;
EXECUTE stmt1;
OPEN c;
FETCH c INTO v1,v2;
SELECT v1,v2;
END//
' DECLARE cur1 CURSOR FOR SELECT Name FROM uTable WHERE aCond;' is not possible mysql does not do variable substitution (for table name). Your read loop is infinite because you don't declare a continuation handler and test for not found in the read loop.
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.
I am working on a MySQL procedure that creates a summary of one of my tables. The procedure retrieves a dataset and loops through it using a cursor. For each iteration of the loop, the procedure updates another table. The problem I'm having is the loop ends after a single iteration, event though I know that the query I'm running retrieves more than one row.
BEGIN
# Variable declaration section omitted for brevity
DECLARE cur CURSOR FOR SELECT
t.result_id,
t.athlete_id, t.`first`, t.middle, `last`, t.pref, t.birth,t.uss,
t.club_id,t.code,t.club_name,
t.meet_name,t.meet_id,t.`start`,t.`end`,
MIN(t.time) as time,t.age,t.type
FROM sometable t GROUP BY club_id ORDER BY time asc,t.start desc,club_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO result_id,athlete_id, first_name, middle, last_name, pref, birth,uss,
club_id,club_code,club_name,
meet_name,meet_id,start_date,end_date,
result_time,age,type;
IF done=1 THEN
LEAVE read_loop;
END IF;
SET last_time = result_time;
INSERT INTO toptimes(`result_id`,`club_id`,`agegroup`,`sex`,`distance`,`course`,`stroke`,`data`,`published`)
VALUES(result_id,club_id,AgeGroupID,sex,distance,course,stroke,json,0);
END LOOP read_loop;
CLOSE cur;
END
I'm not clear what the problem is. When I run the select query manually, I get back several rows. Is there a problem running an insert statement inside the loop?
Your code chunk looks good to me.
How do you know that it's running only one iteration (i'm not seeing any
print or select statement for debug purpose)?
Are you getting any error while executing the stored procedure?
I tried to replicate the similar code with "sakila" database (mysql sample db). It's working perfectly. Please check this sql code sample, if it helps you.
DROP PROCEDURE IF EXISTS usp_select_dummy_data ;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE usp_select_dummy_data()
BEGIN
-- Declare your variables
Declare _var_actor_id int default 0;
DECLARE _var_film_id int default 0;
-- Declare variable used for cursor and loop control
DECLARE done int;
DECLARE loop_counter INT DEFAULT 0;
-- Declare the cursor
DECLARE cur CURSOR FOR
SELECT
actor_id, film_id
FROM film_actor;
-- Declare handlers
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- Open the cursor
OPEN cur ;
-- Start the loop
read_loop: LOOP
FETCH cur
INTO _var_actor_id, _var_film_id ;
-- break out of the loop if
-- 1. if there is no rows or
-- 2. we've processed them all
IF done = 1 THEN
CLOSE cur ;
LEAVE read_loop ;
END IF;
-- Count the number of times looped
SET loop_counter = loop_counter + 1 ;
END LOOP read_loop ;
-- print the loop count
select loop_counter;
END
This is what i tried. I couldnt get my values inserted into table. can anyone help me out ..
DELIMITER $$
USE `SampleDB`$$
DROP PROCEDURE IF EXISTS `Sample`$$
CREATE PROCEDURE `SampleDB`.`Sample`()
BEGIN
#declare variable
DECLARE tenantName VARCHAR(255);
DECLARE tenantAddress VARCHAR(255);
DECLARE done INT DEFAULT FALSE;
DECLARE cur1 CURSOR FOR SELECT tenant_name,tenant_address FROM tenant;
#open cursor
OPEN cur1;
#starts the loop
the_loop: LOOP
#get the values of each column into our variables
FETCH cur1 INTO tenantName,tenantAddress;
IF done THEN
LEAVE the_loop;
END IF;
#Insert it
INSERT INTO tenant(tenant_name,tenant_address)
VALUES (tenantName,tenantAddress);
END LOOP the_loop;
CLOSE cur1;
END$$
DELIMITER ;
Indeed lack 13.6.7.2. DECLARE ... HANDLER Syntax:
...
DECLARE cur1 CURSOR FOR SELECT tenant_name, tenant_address FROM tenant;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
#open cursor
...
But do you really need a cursor? With a statement like this, you can avoid the cursor:
INSERT INTO `tenant` (`tenant_name`, `tenant_address`)
SELECT `tenant_name`, `tenant_address` FROM `tenant`;
I have created a stored procedure in Mysql, as :
delimiter $$
drop procedure if exists test9$$
Create procedure test9(test_type varchar(20))
Reads sql data
begin
Declare 1_id int;
Declare 1_date varchar(20);
Declare done int default 0;
Declare cur1 cursor for
select id,name from buyers where ticket_type='test_type';
Declare Continue handler for not found set done=1;
Create temporary table if not exists ticketninja.history2(n_id int,n_date varchar(20));
Open cur1;
hist_loop:loop
fetch cur1 into 1_id,1_date;
if done=1 then
leave hist_loop;
end if;
insert into ticketninja.history2(n_id ,n_date) values(1_id,1_date);
End loop hist_loop;
close cur1;
select * from history2;
drop table history2;
End;
$$
delimiter ;
but when i call it using,
call test9('platinum');
it returns an error saying :
#1312 - PROCEDURE ticketninja.test1 can't return
a result set in the given context
what i am doing wrong here?
I think you need an OUT variable (see first code sample here)