Stored procedure error on CALL - mysql

I am trying to call a procedure which compiles successfully but on calling I get this error:
Query: call proc5
Error Code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1
This is my Stored procedure:
DELIMITER $$
CREATE DEFINER = `root` #`localhost` PROCEDURE `proc5` ()
BEGIN
DECLARE done BOOL DEFAULT FALSE ;
DECLARE tablename VARCHAR (100) ;
DECLARE tracktables CURSOR FOR
SELECT
TABLE_NAME
FROM
information_schema.TABLES
WHERE TABLE_SCHEMA = 'db1' ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE ;
OPEN tracktables ;
myloop :
LOOP
FETCH tracktables INTO tablename ;
IF done
THEN CLOSE tracktables ;
LEAVE myloop ;
END IF ;
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM ',
#tablename
) ;
PREPARE stmt1 FROM #s ;
EXECUTE stmt1 ;
DEALLOCATE PREPARE stmt1 ;
END LOOP ;
END $$
DELIMITER ;
Actually, I want to select all the tables from a database and insert those tables into one table which is in another database using MySQL Cursors. And when I call this stored procedure I get the above error.

The problem is that you are mixing declared variables and impromtu #vars.
var -> tablename does not equal var -> #tablename.
Change the set line to:
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM `'
,tablename
,'`'
) ;
Now it should work.
The backticks ` should not be needed, but are there just in case.

Related

MySQL - Using dynamicsql on Update

I'm working with MySQL 5.6 and trying to a simple procedure seen below.
drop procedure if exists procsBook;
DELIMITER $$
CREATE PROCEDURE procsBook()
main:begin
DECLARE abc VARCHAR(256);
DECLARE def VARCHAR(256);
DECLARE field_name2 VARCHAR(256);
DECLARE field_names VARCHAR(256);
DECLARE bkid BIGINT(20);
SET abc:= NULL;
SET def:= NULL;
SET field_name2:= NULL;
SET field_names:= NULL;
SET bkid:= 0;
select a.field_name,b.column_name into abc,def from table1 a join table2 b where a.field_label=b.field_label and b.table_name='Table13' and b.section_name='English' group by a.field_name limit 1;
IF(abc is not null)
then
IF (SUBSTRING(abc,7,1)=1)
THEN
SELECT book1,bookId INTO field_names,bkid FROM shelf1 WHERE rowstate=0;
SET #vSelectQury = CONCAT('update shelf2 set def = ' , field_names, ' where book_id = ', bkid);
PREPARE vDynamicSSql FROM #vSelectQury;
EXECUTE vDynamicSSql;
DEALLOCATE PREPARE vDynamicSSql;
END IF;
END IF;
END $$
DELIMITER ;
Call:
call procsBook();
This is throwing the following error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where book_id = 22' at line 1
Any help please?
I think you need to add quotes around field_names.
SET #vSelectQury = CONCAT('update shelf2 set ', def, ' = \'' , field_names,
'\' where book_id = ', bkid); PREPARE vDynamicSSql FROM #vSelectQury;
(or if your setup is different you may need to change the escaping for ' character)
Updated you should not directly use def, but use the value of def in this case.

Error when calling a SP from another one

I have created the following MySQL SP successfully..
CREATE DEFINER=`root`#`%` PROCEDURE `Common_Proc_Create_NewId`
(
TableName VARCHAR(250),
ColumnName VARCHAR(150),
OUT ReturnId BIGINT
)
BEGIN
DECLARE varb BIGINT;
SET #NewId:= CONCAT('SELECT (IFNULL(MAX(', ColumnName, '), 0) + 1) INTO ', varb, ' FROM ', TableName);
PREPARE Stmnt FROM #NewId;
EXECUTE Stmnt;
DEALLOCATE PREPARE Stmnt;
SET ReturnId = varb;
END$$
But when this was called from another SP I got the following error:
Error Code: 1064 You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'NULL' at line 1
Calling SP
CREATE DEFINER=`root`#`%` PROCEDURE `Masters_Proc_Create_BranchType`(
BranchTypName VARCHAR(100)
)
BEGIN
CALL Common_Proc_Create_NewId('Masters_BranchType', 'BranchTypeId', #Id);
INSERT INTO Masters_BranchType (BranchTypeId, BranchTypeName) VALUES (#Id, BranchTypName);
SELECT #Id;
END$$
In your stored procedure Common_Proc_Create_NewId the part into varb was causing the issue and think it's not allowed that way in a prepared statement (not sure though). Instead the way you are doing, try like below and it works fine (a sample code included)
delimiter //
CREATE PROCEDURE dynamic1(IN tbl VARCHAR(64), IN col VARCHAR(64), OUT ret int)
BEGIN
SET #s = CONCAT('SELECT #i := (IFNULL(MAX(', col, '), 0) + 1) FROM ', tbl);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set ret = #i;
END
//
delimiter ;
call dynamic1('test1','col',#id);
select #id;

MySQL 'Group' syntax error when no Group statement?

I'm trying to run the below script against MySQL server but I get the error:
ERROR 1064 (42000) at line 28: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Group' at line 1
Here's the sql script:
/* Remove old indexes */
USE production;
DROP PROCEDURE IF EXISTS DropIndexes;
DELIMITER //
CREATE PROCEDURE DropIndexes()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE tbl, idx VARCHAR(1000);
DECLARE index_cursor CURSOR FOR SELECT TABLE_NAME, INDEX_NAME FROM information_schema.statistics WHERE table_schema = 'production' AND INDEX_NAME LIKE 'ix_%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN index_cursor;
read_loop: LOOP
FETCH index_cursor INTO tbl, idx;
IF done THEN
LEAVE read_loop;
END IF;
SET #s = CONCAT('DROP INDEX ',idx,' ON ',tbl);
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END LOOP;
CLOSE index_cursor;
END//
DELIMITER ;
CALL DropIndexes();
DROP PROCEDURE IF EXISTS DropIndexes;
Given the error makes no sense with no 'Group' statement I have no idea what the problem is.
Maybe you have an index or table named group. You need to escape reserved words like group with backticks. Try
SET #s = CONCAT('DROP INDEX `',idx,'` ON `',tbl,'`');
It must be your Table name selected from the statistics table. To get it accepted enclose it in back-ticks. And though not required on your index name ( because it starts with ix_ ), better you practice using the back-ticks.
SET #s = CONCAT( 'DROP INDEX `' , idx, '` ON `', tbl, '`' );

A loop for adding multiple columns into a table in mysql

The purpose of the following loop is to create 10 columns and name them as'col_20','col_21'...
.This loop could be created but a syntax error occurred when I tried to run it.
This is what got after I called MYLOOP() in Mysql
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0' at line 1"
DELIMITER $$
CREATE PROCEDURE MYLOOP()
BEGIN
DECLARE i int;
DECLARE str varchar(255);
SET i = 20;
WHILE i < 30 DO
SET str = CONCAT('col_',i);
SET #sql = 'ALTER TABLE TEST ADD '+ str + ' INT;';
SET i = i + 1;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END WHILE;
END $$
DELIMITER ;
CALL MYLOOP();

Error when calling Mysql Stored procedure

This is my stored procedure to search throgh all databases,tables and columns.
This procedure got created with out any error.
DELIMITER $$
DROP PROCEDURE IF EXISTS `mydb`.`get_table`$$
CREATE DEFINER=`root`#`%` PROCEDURE `get_table`(in_search varchar(50))
READS SQL DATA
BEGIN
DECLARE trunc_cmd VARCHAR(50);
DECLARE search_string VARCHAR(250);
DECLARE db,tbl,clmn CHAR(50);
DECLARE done INT DEFAULT 0;
DECLARE COUNTER INT;
DECLARE table_cur CURSOR FOR
SELECT concat('SELECT COUNT(*) INTO #CNT_VALUE FROM ',
table_schema,'.', table_name,
' WHERE ', column_name,' REGEXP ''',in_search,''''
)
,table_schema,table_name,column_name
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA NOT IN ('mydb','information_schema');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
# #Truncating table for refill the data for new search.
PREPARE trunc_cmd FROM 'TRUNCATE TABLE temp_details';
EXECUTE trunc_cmd ;
OPEN table_cur;
table_loop:LOOP
FETCH table_cur INTO search_string,db,tbl,clmn;
# #Executing the search
SET #search_string = search_string;
SELECT search_string;
PREPARE search_string FROM #search_string;
EXECUTE search_string;
SET COUNTER = #CNT_VALUE;
SELECT COUNTER;
IF COUNTER>0 THEN
# # Inserting required results from search to table
INSERT INTO temp_details VALUES(db,tbl,clmn);
END IF;
IF done=1 THEN
LEAVE table_loop;
END IF;
END LOOP;
CLOSE table_cur;
# #Finally Show Results
SELECT * FROM temp_details;
END$$
DELIMITER ;
But when calling this procedure following error occurs.
call get_table('aaa')
Error Code : 1064 You have an error in
your SQL syntax; check the manual that
corresponds to your MySQL server
version for the right syntax to use
near 'delete REGEXP 'aaa'' at line 1
(0 ms taken)
Where does "delete" come from? Do you have a column_name with that name? If so, use better names, not reserved ones, or use nasty backticks ` or ANSI-quotes " around the column name.
Constructions like this are vulnerable to SQL injection.