Using a variable as a column name in a stored procedure? - mysql

Here I wrote a mysql procedure which select all text type field of specified database 'wp'
and I want to update every text type field row appending extra string via CONCAT function.
after I call test2 , error shows:
Query : call test2()
Error Code : 1146
Table 'wp._tbl' doesn't exist
Execution Time : 00:00:00:000
Transfer Time : 00:00:00:000
Total Time : 00:00:00:000
---------------------------------------------------
mysql regards _tbl as a string but not a variable.
So can I correct this?
code:
DELIMITER $$
USE `wp`$$
DROP PROCEDURE IF EXISTS `test2`$$
CREATE
PROCEDURE `test2`()
BEGIN
DECLARE _tbl VARCHAR(100);
DECLARE _cl VARCHAR(100);
DECLARE notFound INT DEFAULT 0;
DECLARE cur CURSOR FOR SELECT table_name,column_name FROM information_schema.columns WHERE table_schema = 'wp' AND data_type ='text';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET notFound =1;
OPEN cur;
WHILE notFound = 0 DO
FETCH cur INTO _tbl,_cl;
UPDATE _tbl SET _cl = CONCAT(_cl,'extra string goes here.....');
IF NOT noFound THEN SET notFound = 0;
END IF;
END WHILE;
CLOSE cur;
END$$
DELIMITER ;

You'll need to use prepared statements.
Also see How To have Dynamic SQL in MySQL Stored Procedure

Related

MySQL8 Procedure - Use Parameters in Cursor

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.

Trying to add an additional value to an existing value in a column for all the rows that are retrieved using a stored procedure for

I have spent quite a long time to figure out.. so my update statement is affecting 0 rows although I know for a fact that it should affect at least affect more than a few rows as I have tried as a standalone. In place of update statement I tried select statement and it is working so does that mean that update statement is not supposed to work in stored procedure.. I kinda doubt it.. so I would like to get a second opinion.
my stored procedure code here:
DELIMITER $$
CREATE PROCEDURE updateKeywordsInRIConsole(in retailerId int )
BEGIN
declare key_words varchar(200) default null;
declare grpid bigint(20);
declare finished bool default false;
declare cur1 cursor for
select Keywords, GRPID
from RIConsole
where RetailerID = retailerId
and DateCreated > date(now()) - interval 1 year
and INSTR(Keywords, "offer_page") = false;
declare continue handler for not found set finished = 1;
declare exit handler for sqlexception
begin
show errors;
end;
declare exit handler for sqlwarning
begin
show warnings;
end;
open cur1;
start_loop: loop
fetch cur1 into key_words, grpid;
if finished = 1 then
leave start_loop;
end if;
update RIConsole set Keywords = concat(key_words, " ",
"offer_page") where GRPID = cast(grpid as signed); <-- this code not working...I called it with cast function to make sure.. and i also tried without it.
end loop start_loop;
close cur1;
END $$
DELIMITER ;
DROP PROCEDURE updateKeywordsInRIConsole;
Yes, you can do an UPDATE in a stored procedure.
If you are happy with your SELECT, you could do the while thing in a single statement. e.g.
CREATE PROCEDURE updateKeywordsInRIConsole(IN retailerId INT)
BEGIN
UPDATE RIConsole
SET Keywords = CONCAT(Keywords, " ", "offer_page")
WHERE where RetailerID = retailerId
AND DateCreated > DATE(NOW()) - INTERVAL 1 YEAR
AND INSTR(Keywords, "offer_page") = false;
END
;

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 ;

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 ;

How to replace a string with another in whole tables in a mysql database

I want to replace a string with another in full database. Assume database name is "A" and it contains 101 tables. I want to change "subhojit" to "jeet" in all table's column if it contains "subhojit".
Is it possible in MySql?
Need to write procedure?
Please reply.
update thetable set thecol = replace(thecol, 'subhojit', 'jeet')
where thecol like '%subhojit%';
From here.
This is a bit rough and ready (exception handling for example). But hopefully you can tidy it up for your own purposes:
DELIMITER $$
CREATE PROCEDURE `replace_value_in_all_cols`(IN i_schema varchar(250),IN i_fromVal varchar(250),IN i_toVal varchar(250), OUT o_errMessage varchar(250))
BEGIN
ALL_TEXT_COLUMNS : BEGIN
DECLARE noMoreRows boolean;
DECLARE db varchar(250);
DECLARE tbl varchar(250);
DECLARE col varchar(250);
DECLARE allTextCols CURSOR FOR
select c.table_schema,c.table_name,c.column_name
from information_schema.columns c
where c.table_schema = i_schema
and lower(data_type) in ('char','text','varchar');
DECLARE EXIT HANDLER for SQLEXCEPTION set o_errMessage := "Some error message";
declare continue handler for not found set noMoreRows := true;
open allTextCols;
UPDATE_LOOP : loop
fetch allTextCols
into db,tbl,col;
if noMoreRows then
close allTextCols;
leave UPDATE_LOOP;
end if;
SET #update_stmt:=CONCAT("UPDATE ",db,".",tbl," SET ",col," = replace(",col,",'",i_fromVal,"','",i_toVal,"');");
PREPARE update_stmt FROM #update_stmt;
EXECUTE update_stmt;
DEALLOCATE PREPARE update_stmt;
end loop UPDATE_LOOP;
END ALL_TEXT_COLUMNS;
END$$
DELIMITER ;
Then you can do something like:
call `replace_value_in_all_cols`("A",'subhojit','jeet', #err);