MySQL 'Group' syntax error when no Group statement? - mysql

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, '`' );

Related

MySQL: IF EXISTS ... TRUNCATE

Want to truncate a table if it exists:
IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'mytable') TRUNCATE mytable
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 'IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE
TABLE_NAME = 'mytable') ' at line 1
I tried also to add THEN after ) but the problems seems to be at IF.
You need the two statements below to do that:
create table if not exists <mytable>;
truncate table <mytable>;
So I had a similar issue, and to resolve it, I created this procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `truncate_if_exist`$$
CREATE PROCEDURE `truncate_if_exist`(IN tbl_name VARCHAR(150) )
BEGIN
IF EXISTS( SELECT 1 FROM information_schema.TABLES WHERE table_name = tbl_name AND table_schema = DATABASE()) THEN
SET #query = CONCAT('TRUNCATE ', tbl_name);
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END $$
DELIMITER ;
And then called it for each table that I wanted to truncate
for example:
CALL truncate_if_exist('users');
CALL truncate_if_exist('random_tmp_table');
Obviously, if the table does not exist, it will not run the TRUNCATE command.

Create a new MySQL Database from existing db with up to 10000 rows of data from each table

I am trying to create a database with some data not all. I don't need 1M+ records to do what I need so I am okay with only 10000 rows.
I figured I can use a stored procedure to loop through all the table and manually create each table and insert only 10000 rows.
I created a stored procedure like this
CREATE DEFINER=`root`#`10.%` PROCEDURE `createNewDatabase`(in db_name varchar(100), in new_db_name varchar(100))
BEGIN
DECLARE finish INT DEFAULT 0;
DECLARE tbl VARCHAR(100);
DECLARE cur_tables CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = db_name AND TABLE_TYPE='BASE TABLE';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finish = 1;
OPEN cur_tables;
my_loop: LOOP
FETCH cur_tables INTO tbl;
IF finish = 1 THEN
LEAVE my_loop;
END IF;
SET #str = CONCAT('DROP TABLE IF EXISTS `', new_db_name, '`.`' , tbl , '`; CREATE TABLE `', new_db_name, '`.`' , tbl , '` LIKE `', db_name , '`.`', tbl,'`; INSERT INTO `', new_db_name , '`.`' , tbl, '` SELECT * FROM `', db_name ,'`.`', tbl , '` LIMIT 10000;');
PREPARE stmt FROM #str;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur_tables;
END
Then I called it like this
CALL createNewDatabase('baseTable', 'newTable');
But I run the procedure I get the following error
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CREATE TABLE `newTable`.`account_addresses` LIKE `baseTable`.`account_addres' at line 1
if I added the following 2 lines after just before the prepare statement
SELECT #str;
LEAVE my_loop;
I get the following queries which works if I executed them manually
DROP TABLE IF EXISTS `newTable`.`account_addresses`;
CREATE TABLE `newTable`.`account_addresses` LIKE `baseTable`.`account_addresses`;
INSERT INTO `newTable`.`account_addresses` SELECT * FROM `newTable`.`account_addresses` LIMIT 10000;
CREATE TABLE `newTable`.`account_addresses` LIKE `baseTable`.`account_addresses`; INSERT INTO `newTable`.`account_addresses` SELECT * FROM `baseTable`.`account_addresses` LIMIT 10000;
What am I doing wrong here? Why it is erroring?
Quote from mysql's documentation on PREPARE:
The text must represent a single statement, not multiple statements.
You are trying to execute a drop table and a create table statement, insert records in 1 prepared statement and this is not allowed. Have 3 separate prepared statement for the 3 commands.

Stored procedure to replace a string with another in an entire database

I am trying to create a procedure to change a string in an entire database... after a lot of searching I have come up with this procedure, but it gives an error. The procedure is:
BEGIN
declare t,c varchar(100);
declare TABLES cursor for SELECT table_name, column_name
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='MY_DATABSE';
declare exit handler for 1329 begin end;
open tables;
looping: loop
fetch tables into t,c;
SET #s1= CONCAT('UPDATE ',
'MY_DATABASE', '.', t, ' SET ',
c, ' = replace(', c,', \'', old, '\'', ' , ', '\'', new, '\')');
PREPARE stmt FROM #s1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end loop;
close tables;
END
And the error when calling the procedure with any parameter is the well known 1064 error in syntax: check the manual that corresponds to your MySQL server version for the right syntax to use near 'column_to_update(c) = replace(column_to_update(c), 'old' , 'new')' at line 1

MySQL Stored Procedure with a hyphen in value

I have a stored procedure that works, but when I pass a value with a hyphen in it, it errors.
I call my procedure with a value like call create('server-v01',555); and I get the following error:
ERROR 1064 (42000): 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 '-v01' at line 1
My procedure is as follows:
DELIMITER $$
CREATE PROCEDURE ct(tname varchar(20), sessionsnum INT(11))
BEGIN
DECLARE maxnum INT;
SET #s = CONCAT('INSERT INTO sessions_poll (server_name,sessions_num) VALUES(''',tname,''',',sessionsnum,')');
PREPARE stm FROM #s;
EXECUTE stm;
SET #s = CONCAT('DROP TABLE IF EXISTS ', tname);
PREPARE stm FROM #s;
EXECUTE stm;
SET #s = CONCAT('CREATE TABLE ', tname, ' (num INT, max INT)');
PREPARE stm FROM #s;
EXECUTE stm;
SELECT #maxnum:=max(sessions_num) INTO maxnum FROM sessions_poll WHERE server_name=tname AND DATE(ts)=CURDATE();
SET #s = CONCAT('INSERT INTO ', tname, ' (num,max) VALUES (', sessionsnum,',',maxnum,')');
PREPARE stm FROM #s;
EXECUTE stm;
END $$
DELIMITER ;
My question is, how can I handle a variable with a hyphen in it?
Your question is not how to handle variable with a dash, but how to handle a table with a dash. Your procedure tries to create a table with a name specified in tname. To create (or drop) a table like this you need to quote it with backticks.
DROP TABLE IF EXISTS `server-01`;
In particular you need to
SET #s = CONCAT('DROP TABLE IF EXISTS `', tname, '`');
and the same for other instances.
Whether this is what you really want to do is a question, though ;-)

Stored procedure error on CALL

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.