Bad query in cursol in procedure mysql - mysql

I have a problem with curosr exactly with query : SELECT Crc32 FROM tableName. I want read all rows from Crc32 column and based on the first four characters find a table that has the same name as the four digits
Error:
0 12:58:57 call ShowNewUserComments("User66") Error Code: 1146. Table 'comments.tableName' doesn't exist
Call Procedure:
call ShowNewUserComments("User66");
Code
DELIMITER $$
DROP PROCEDURE IF EXiSTS ShowNewUserComments $$
CREATE PROCEDURE `ShowNewUserComments`(tableName varchar(255)/*, Date TIMESTAMP*/)
BEGIN
DECLARE recordNotFound INTEGER DEFAULT 0;
DECLARE oneRow VARCHAR(10) DEFAULT "";
DECLARE getCrc32,i int (11);
DECLARE myCursor CURSOR FOR SELECT Crc32 FROM tableName;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET recordNotFound = 1;
OPEN myCursor;
set i = 0;
allRows: LOOP
FETCH myCursor INTO oneRow;
set i = i + 1;
IF recordNotFound THEN
LEAVE allRows;
END IF;
END LOOP allRows;
CLOSE myCursor;
END

You can't directly substitute table name from variable into query in MySQL, for that you need to use dynamic sql using PREPARE like this:
DELIMITER $$
DROP PROCEDURE IF EXiSTS ShowNewUserComments $$
CREATE PROCEDURE `ShowNewUserComments`(tableName varchar(255)/*, Date TIMESTAMP*/)
BEGIN
DECLARE recordNotFound INTEGER DEFAULT 0;
DECLARE oneRow VARCHAR(10) DEFAULT "";
DECLARE getCrc32,i int (11);
DECLARE myCursor CURSOR FOR SELECT Crc32 FROM temp_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET recordNotFound = 1;
DROP TEMPORARY TABLE IF EXISTS temp_table;
SET #query1 = CONCAT('CREATE TEMPORARY TABLE temp_table AS
SELECT Crc32
FROM ',tableName,' ');
PREPARE stmt FROM #query1; EXECUTE stmt; DEALLOCATE PREPARE stmt;
OPEN myCursor;
set i = 0;
allRows: LOOP
FETCH myCursor INTO oneRow;
set i = i + 1;
IF recordNotFound THEN
LEAVE allRows;
END IF;
END LOOP allRows;
CLOSE myCursor;
DROP TEMPORARY TABLE IF EXISTS temp_table;
END

Related

Pass a variable into CURSOR's SELECT Query (MySQL)

I'm trying the stored procedure below. However, when i pass the actual column name in 'DECLARE cur1' line, the SP returns correct value but when I pass variable name i.e. input parameter (colName), it returns 0. I've added comments in my code below. Is the code correct?
DROP PROCEDURE IF EXISTS test1.checkHardcodedField;
CREATE PROCEDURE test1.checkHardcodedField(IN textValue CHAR(10), colName CHAR(10), OUT counter VARCHAR(100))
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE temp CHAR(16);
DECLARE i INT DEFAULT 0;
-- Issue with this statement, returns incorrect value.
DECLARE cur1 CURSOR FOR SELECT colName FROM data1;
-- This statement works. MSH3 is actual column name
-- DECLARE cur1 CURSOR FOR SELECT MSH3 FROM data1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO temp;
IF done THEN
LEAVE read_loop;
END IF;
IF temp = textValue THEN
SET i = i + 1;
END IF;
END LOOP;
SET counter = i;
CLOSE cur1;
END;
CREATE PROCEDURE procedure_name (..., fieldname VARCHAR, ...)
BEGIN
CREATE TEMPORARY TABLE tmp (field VARCHAR(10));
SET #sql := CONCAT('INSERT INTO tmp SELECT ', fieldname, ' FROM tablename;');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;
BEGIN
DECLARE cur CURSOR FOR SELECT field FROM tmp;
...
END;
DROP TABLE tmp;
END

Error (2014. Commands out of querys) with all complex querys on MySQL

On all complex querys (returning many results and running long) I get the same error after some time: Error Code: 2014. Commands out of sync; you can't run this command now
e.g.:
## Prozedur Droppen
DROP PROCEDURE IF EXISTS ifob.uspUpdateHeatStatsAll;
SET SQL_SAFE_UPDATES = 0;
## Prozedur erstellen
DELIMITER $$
CREATE DEFINER=`root`#`%` PROCEDURE `uspUpdateHeatStatsAll`()
BEGIN
## Update table
DECLARE _HeatNrDINT int;
DECLARE _count int;
DECLARE _act int;
# Bearbeitungsliste erstellen
DROP TABLE IF EXISTS tmptblColumns;
CREATE TEMPORARY TABLE tmptblColumns (`HeatNrDINT` int) ENGINE = MEMORY;
# Delete old data
# Add columns to workertable
INSERT INTO tmptblColumns (`HeatNrDINT`) SELECT DISTINCT `Input.General.Values.HeatNrDINT` from tblmeasuringvaluesyear;
SET _count = (SELECT count(*) FROM tmptblColumns);
SET _act = 1;
#debug
#SELECT * FROM tmptblColumns;
BEGIN
DECLARE _done BOOL DEFAULT FALSE;
DECLARE column_cursor CURSOR FOR SELECT `HeatNrDINT` FROM `tmptblColumns`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;
#Alte Daten löschen
OPEN column_cursor;
FETCH column_cursor INTO _HeatNrDINT;
read_loop: LOOP
SELECT CONCAT('Bearbeite:',_HeatNrDINT,'(',_act,'/', _count,')') as `Status`;
CALL uspUpdateHeatStats(_HeatNrDINT);
SET _act = _act+1;
FETCH column_cursor INTO _HeatNrDINT;
IF _done THEN
LEAVE read_loop;
END IF;
END LOOP;
CLOSE column_cursor;
# Execute STMT
END;
END$$
DELIMITER ;
#TEST
CALL uspUpdateHeatStatsAll();
SELECT * FROM tblheatdata;
works for 50 loops and then it quits.
I have also run into this problem. The maximum number of result sets in MySQL Workbench defaults to 50. It will crash after 50 because the previous results have not been retrieved.

How to update column in every table which name starts with special characters

I need to update special column in every table that which name start with :-
`REPORT_<"DATE PATERN">`
How actually I can do it?.
upd:
I've tried to write stored procedure, but I'm not familiar with it, so it does not work:
DELIMITER $$
DROP PROCEDURE IF EXISTS `debug_msg`$$
CREATE PROCEDURE debug_msg(enabled INTEGER, msg VARCHAR(255))
BEGIN
IF enabled THEN BEGIN
select concat("** ", msg) AS '** DEBUG:';
END; END IF;
END $$
DELIMITER $$
DROP PROCEDURE IF EXISTS changeColumnType;
CREATE PROCEDURE changeColumnType ()
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE tableName varchar(100);
DEClARE table_cursor CURSOR FOR
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE '%REPORT_%';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN table_cursor;
get_tableName: LOOP
FETCH table_cursor INTO tableName;
IF v_finished = 1 THEN
LEAVE get_tableName;
END IF;
call debug_msg(1, tableName);
ALTER TABLE tableName MODIFY COLUMN TIME VARCHAR(8);
END LOOP get_tableName;
CLOSE table_cursor;
END$$
DELIMITER ;
I have the following error:
ERROR 1146 (42S02): Table 'test.tablename' doesn't exist.
I fails on this step ALTER TABLE tableName MODIFY COLUMN TIME VARCHAR(8);
Resolved it by adding prepared statement
SET #table = tableName;
SET #s1 = CONCAT('ALTER TABLE ', #table, ' MODIFY COLUMN TIME VARCHAR(8);');
PREPARE stmt FROM #s1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Cursor in Procedure does not return any values

I have a database where temp tables are created, those table names are randomly generated and saved in Checkouts.unid. I want to drop all those tables and truncate the table Checkouts. I thought the niftiest solution would be a procedure, but it will not work:
DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
SQL SECURITY INVOKER
BEGIN
DECLARE `t` VARCHAR(64);
DECLARE `ch` CURSOR FOR SELECT `unid` FROM `Checkouts`;
OPEN `ch`;
drop_tables: LOOP
FETCH `ch` INTO `t`;
DROP TABLE IF EXISTS `t`;
END LOOP;
CLOSE `ch`;
TRUNCATE TABLE `Checkouts`;
END
I always get "No data - zero rows fetched, selected, or processed" although those tables are there and the table Checkouts is not empty though.
You have to add something like this in order to end your loop:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET ...;
See example in the documentation.. E.g. ...
DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
SQL SECURITY INVOKER
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE `t` VARCHAR(64);
DECLARE `ch` CURSOR FOR SELECT `unid` FROM `Checkouts`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN `ch`;
drop_tables: LOOP
FETCH `ch` INTO `t`;
IF done THEN
LEAVE drop_tables;
END IF;
DROP TABLE IF EXISTS `t`;
END LOOP;
CLOSE `ch`;
TRUNCATE TABLE `Checkouts`;
END
Otherwise you will get an error once you reached the end of your cursor.
I got it working with this:
DROP PROCEDURE IF EXISTS `spCheckoutsCleanup`;
CREATE PROCEDURE `spCheckoutsCleanup` ()
SQL SECURITY INVOKER
BEGIN
DECLARE done int DEFAULT 0;
DECLARE t CHAR(64);
DECLARE ch CURSOR FOR SELECT `unid` FROM `Checkouts`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN ch;
drop_table: LOOP
FETCH ch INTO t;
IF done = 1 THEN
LEAVE drop_table;
END IF;
SET #sql := CONCAT('DROP TABLE IF EXISTS `', t, '`');
PREPARE dropt FROM #sql;
EXECUTE dropt;
END LOOP;
CLOSE ch;
TRUNCATE TABLE `Checkouts`;
END;
CALL spCheckoutsCleanup;

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 ;