MySQL8 Procedure - Use Parameters in Cursor - mysql

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.

Related

mysql stored procedure variable error

Hi I am finding my way round MySQL trying to migrate data from MSsql for the first time. I have created a stored procedure that clear all the tables down so I can import the data repeatedly as I test and alter things. I thought I had this pretty well figured but I am unsure how to get the actual value of the variable to go with the delete statement. Thanks for any assistance
DELIMITER $$
CREATE PROCEDURE ClearData ()
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_TableName varchar(100) DEFAULT "";
-- declare cursor for list of tables to clear
DEClARE TableToRemove CURSOR FOR
SELECT TABLE_NAME from information_schema.tables where table_type ='BASE TABLE';
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN TableToRemove;
ClearData: LOOP
FETCH TableToRemove INTO v_TableName;
IF v_finished = 1 THEN
LEAVE ClearData;
END IF;
--This is the problem how do I get the value of v_TableName
delete from `v_TableName`;
END LOOP ClearData;
CLOSE TableToRemove;
END$$
DELIMITER ;

MySQL Stored Proc's Param with IN Varchar() not looping the cursor

I am trying to get the following to work while testing Stored Procedures, but it doesnt. Can someone point out whats wrong?
The idea is to take in a list of userids as csv, and return their email addresses as csv.
(This is just for testing stored proc. in mysql. I know I could just simply select it with regular sql query)
DELIMITER $$
DROP PROCEDURE IF EXISTS `build_email_list`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `testing_email_list`(IN user_ids VARCHAR(200), INOUT email_list VARCHAR(4000))
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_email VARCHAR(100) DEFAULT "";
DECLARE email_cursor CURSOR FOR
SELECT email_address FROM users WHERE id IN (user_ids);
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;
SET email_list = CONCAT(v_email, ";", email_list);
END LOOP get_email;
CLOSE email_cursor;
END$$
DELIMITER ;
Calling it like this:
SET #email_list = "";
CALL testing_email_list("1,8", #email_list);
SELECT #email_list;
However, it only returns the first id passed (i.e. 1). But when I change the stored proc to directly take these ids with the following it works fine:
DECLARE email_cursor CURSOR FOR
SELECT email_address FROM users WHERE id IN (1,8);
This is driving me nuts, what am I missing here?
Thanks a lot.

prepared statement in stored procedure not refreshing

Using a dynamically created view WITHIN a Loop in this MySQL stored procedure. The problem I'm having is the contents of temp_controller_view view only reflect the result from the view's first creation (e.g. first loop) as if the statement CREATE OR REPLACE VIEW isn't being read.
Obviously I'm trying to get the view to update upon each Looping so that I can work with the contents of the dynamic view
MYSQL ##VERSION > 5.1.61
DROP procedure if exists SITETOEPRISE;
DELIMITER //
CREATE PROCEDURE SITETOEPRISE()
BEGIN
DECLARE bDone INT;
DECLARE sid int(11); -- or approriate type
DECLARE curr_site_db VARCHAR(10);
DECLARE Var3 VARCHAR(50);
DECLARE site_curs CURSOR FOR SELECT siteid FROM sites;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN site_curs;
SET bDone = 0;
site_loop : LOOP
FETCH site_curs INTO sid;
IF bDone THEN
CLOSE site_curs;
LEAVE site_loop;
END IF;
select sid as 'sid_in_loop';
SET #dyn_sql = CONCAT('CREATE OR REPLACE VIEW `temp_controller_view` AS SELECT * from site',sid,'.controller;');
select #dyn_sql;
PREPARE stmt_dyn_view FROM #dyn_sql;
EXECUTE stmt_dyn_view;
DEALLOCATE PREPARE stmt_dyn_view;
select * from temp_controller_view;
drop view temp_controller_view;
END LOOP;
END
//
DELIMITER ;

MySQL print values of variables inside a function

I have a MySQL function. Inside this function I want to print the values of variables when it runs.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` FUNCTION
`updateCompanyName`(companyName varchar(200)) RETURNS varchar(200)
CHARSET latin1 BEGIN
declare modifiedCompanyName varchar(200);
DECLARE keywordToRemove varchar(200);
DECLARE cur1 CURSOR FOR SELECT name FROM company_remove_keywords;
select regex_replace('[^a-zA-Z 0-9]', "",companyName) into modifiedCompanyName;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO keywordToRemove;
select keywordToRemove;
select replace_ci(modifiedCompanyName,
concat(" ",keywordToRemove," ")," ")
into modifiedCompanyName;
select replace_ci(modifiedCompanyName,
concat(" ",keywordToRemove),"")
into modifiedCompanyName;
END LOOP;
CLOSE cur1;
return modifiedCompanyName;
END
What is the best way to print the values: keywordToRemove and modifiedCompanyName?
You can create table (or temporary table) to store debug information, and insert values you need to this table.
Also, you can easy debug stored procedures/functions/triggers with GUI tool - Debugger for MySQL (try trial version).

Mysql stored procedure giving error at runtime

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)