Syntax Error in MySQL Dynamic Query - mysql

I've been facing this issue in MySQL since a long time. I've a dynamic query as below in my stored procedure,
delimiter //
CREATE PROCEDURE test_proc ()
BEGIN
DECLARE var INT DEFAULT 1;
DECLARE id VARCHAR(500) DEFAULT '0';
WHILE var <= 10
DO
SET id = CONCAT(id ,',',(SELECT CAST(id AS CHAR) FROM test_client WHERE Rank = var));
SET var = var + 1;
END WHILE;
SET SQL_QUERY = CONCAT('
CREATE TEMPORARY TABLE t1
AS
SELECT *
FROM test WHERE id IN (',id,');');
SET SQL_QUERY1 = CONCAT('
CREATE TEMPORARY TABLE t2
AS
SELECT *
FROM test1 WHERE id IN (',id,')');
SET #SWV_Stmt = CONCAT(SQL_QUERY,SQL_QUERY1);
PREPARE SWT_Stmt FROM #SWV_Stmt;
EXECUTE SWT_Stmt;
DEALLOCATE PREPARE SWT_Stmt;
END //
delimiter ;
When I create and execute this, I get below 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 'CREATE TEMPORARY TABLE t2 AS SELECT *' at line 5
Can anyone please provide a reason and solution for this?
Thanks in Advance...

That's not a single statement, that is two. The documentation states:
The text must represent a single statement, not multiple statements.

Related

Error Code: 1064. You have an error in your SQL syntax; near '' at line 2

Does anyone see where the mistake can be? been dealing with this one all afternoon. Workbench isn't very useful in pointing out the mistakes.
It appears the next mistake in my code
CALL pCityMean('Spain') 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 '' at line 2.
DELIMITER $$
DROP PROCEDURE IF EXISTS pCityMean $$
CREATE PROCEDURE pCityMean (IN vPais VARCHAR(30))
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE vID INT;
DECLARE cur1 CURSOR FOR SELECT distinct id_city FROM world_temp_stats.temp_by_city where id_country=(SELECT id_country FROM world_temp_stats.country where Name=vPais);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
bucle1: LOOP
FETCH cur1 INTO vID;
IF done = 1 THEN
LEAVE bucle1;
END IF;
SET #nomCiutat = (SELECT name FROM world_temp_stats.city WHERE id = vID);
SET #tablaCiutat = CONCAT ("SELECT year(dt), count(AverageTemperature), ROUND(avg(AverageTemperature), 2) INTO OUTFILE '",UCASE(vPais),"_",UCASE(#nomCiutat),"_temp_analisis.csv' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' FROM world_temp_stats.temp_by_city where id_country=(SELECT id_country FROM world_temp_stats.country where Name='",vPais,"' and id_city=",vID," group by year(dt)");
PREPARE execucio FROM #tablaCiutat;
EXECUTE execucio;
DEALLOCATE PREPARE execucio;
END LOOP bucle1;
CLOSE cur1;
END $$
DELIMITER ;
CALL pCityMean('Spain');
I can eyeball your query and I see that you forgot a closing parenthesis.
SET #tablaCiutat = CONCAT ("SELECT ...
where id_country=(
SELECT id_country FROM world_temp_stats.country
where Name='",vPais,"' and id_city=",vID," group by year(dt)
");
I think you got mixed up because year(dt) ends in a right-paren, but you need one more to close the subquery. Something like the following:
SET #tablaCiutat = CONCAT ("SELECT ...
where id_country=(
SELECT id_country FROM world_temp_stats.country
where Name='",vPais,"' and id_city=",vID," group by year(dt)
)
");
You should also use query parameters for dynamic values in your prepared query, instead of string-concatenation.
But if it were me, I would change so many things about this code. Why use INTO OUTFILE, and why use a stored procedure at all? In my experience, MySQL stored procedures are more difficult than writing the code in virtually any client programming language. I hardly ever use MySQL stored procedures.

Mysql: Issue with having limit and offset as variables in Prepared statement in a stored procedure

DELIMITER //
-- Create a stored procedure with params
CREATE PROCEDURE GetProductsList(MainSubcategory VARCHAR(500), SubcategoryChildName VARCHAR(500), OffsetVal INT, NumberOfRecordPerPage INT, orderLowToHigh Boolean)
READS SQL DATA
BEGIN
SET #MainSubcategory = MainSubcategory;
SET #SubcategoryChildName = SubcategoryChildName;
IF orderLowToHigh = true THEN
SET #SortOrder = 'ASC';
ELSE
SET #SortOrder = 'DESC';
END IF;
SET #OffsetVal = OffsetVal;
SET #NumberOfRecordPerPage = NumberOfRecordPerPage;
PREPARE mainQuery FROM "SELECT title, product_category_tree, id, images, price, old_price
FROM PRODUCTS
WHERE MATCH(product_category_tree) AGAINST (MainSubcategory IN NATURAL LANGUAGE MODE) AND
product_category_tree LIKE CONCAT('%',?,' >> ',?,'%')
ORDER BY price ?
LIMIT ?, ?;";
EXECUTE mainQuery USING #MainSubcategory, #SubcategoryChildName, #SortOrder, #OffsetVal, #NumberOfRecordPerPage;
DEALLOCATE PREPARE mainQuery;
END//
-- Change the delimiter again
DELIMITER ;
when I called this procedure I get an 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 '? LIMIT ?, ?' at line 5 0.0026 sec
It looks like I cannot have variables in limit clause. Is there a workaround in mysql?

can't create a table in mysql with dynamic sql

This is my code in MySQL.
USE database;
DROP procedure IF EXISTS CreateTable;
DELIMITER $$
USE ims_data$$
CREATE PROCEDURE CreateTable ()
BEGIN
Set #SqlQuery = Concat('DROP TABLE IF EXISTS mytemptable;');
Set #SqlQuery = Concat(#SqlQuery,'\r\n','create table mytemptable');
Set #SqlQuery = Concat(#SqlQuery,'\r\n','(');
Set #SqlQuery = Concat(#SqlQuery,'\r\n','Column1 int,');
Set #SqlQuery = Concat(#SqlQuery,'\r\n','Column2 varchar(500)');
Set #SqlQuery = Concat(#SqlQuery,'\r\n',');');
Set #SqlQuery = Concat(#SqlQuery,'\r\n','Select * from mytemptable;');
#Select #SqlQuery;
PREPARE Statement From #SqlQuery;
EXECUTE Statement;
DEALLOCATE PREPARE Statement;
END$$
DELIMITER ;
call GetUploadInformation();
I am trying to create a table but it is giving me an 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 'create table mytemptable (Stockist_Code int,Status varchar(500) ); Sele' at line 2
This is the output of query.
DROP TABLE IF EXISTS mytemptable;
create table mytemptable
(
Column1 int,
Column2 varchar(500)
);
Select * from mytemptable;
Which is working fine when executing this code withoug calling the procedure.
PREPARE/EXECUTE can only process one statement at a time. You're trying to execute two with the ;.
The error message gives you a clue in that it ran the two statements together.
You'll have to run them as separate statements.

MySQL: prepared Statement in a stored Procedure - parameter error 1064

I'm creating a sql script for a migration functionality of ours. We want to migrate data from one magento-instance to another (using pure SQL because the import/export of magento is pretty limited).
One of the challenges ist that I want to dynamically alter the AUTO_INCREMENT value of a table so it doesn't need to be done manually in multiple steps. I want to set the AUTO_INCREMENT value to the current-maximum value of the corresponding column + 1.
I prepared the following stored procedure for this:
DELIMITER $$
CREATE PROCEDURE alter_auto_inc_customer()
BEGIN
SELECT #max := MAX(entity_id)+ 1 FROM customer_entity;
PREPARE stmt FROM 'ALTER TABLE customer_entity AUTO_INCREMENT = ?';
EXECUTE stmt USING #max;
END $$
This command runs smoothly. Afterwards the procedure should just be called by a simple statement:
CALL alter_auto_inc_customer();
When I execute the "call"-statement, I get a 1064 Syntax error. It's probably trivial but I can't figure it out for the life of me...
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 '?' at line 1
Does anyone have an idea what the issue is?
I need to get this into one or more stored procedures because I need to be able to run similar statements for multiple tables in the database.
Instead of altering the table structure you can use a trigger to get the max value + 1 before insert data:
DELIMITER $$
DROP TRIGGER IF EXISTS custom_autoincrement_bi$$
CREATE TRIGGER custom_autoincrement_bi BEFORE INSERT ON customer_entity
FOR each ROW
BEGIN
SET NEW.entity_id = select max(entity_id) + 1 from customer_entity;
END$$
DELIMITER ;
But if you want to alter the table from stored procedure
DELIMITER $$
CREATE PROCEDURE alter_auto_inc_customer()
BEGIN
SELECT MAX(entity_id) + 1 into #max FROM customer_entity;
set #sql = concat('ALTER TABLE customer_entity AUTO_INCREMENT = ', #max);
PREPARE stmt FROM #sql;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
END $$

MySQL ALTER TABLE with arguments in stored procedure

In a MySQL migration script, I'm trying to drop all the foreign keys of a table without knowing the name of the constraints themselves. I need this because I can only be aware of the constraints names in a particular database installation, but the script has to work also in other installations where the name is unknown at current script coding time.
Here is my first guess of a stored procedure, but it doesn't work. In particular it complains about the '?' in ALTER TABLE.
DELIMITER $$
DROP PROCEDURE IF EXISTS drop_foreign_key_documents $$
CREATE PROCEDURE drop_foreign_key_documents ( )
BEGIN
WHILE (SELECT COUNT(*) AS index_exists FROM `information_schema`.`TABLE_CONSTRAINTS` c WHERE `c`.`CONSTRAINT_TYPE` LIKE '%FOREIGN%' AND `c`.`TABLE_NAME`='documents' and `c`.`TABLE_SCHEMA`='mydb') > 0 DO
SET #ctype = '%FOREIGN%';
SET #tname = 'documents';
SET #dbname = 'mydb';
SET #n = 'select `CONSTRAINT_NAME` INTO #cname FROM `information_schema`.`TABLE_CONSTRAINTS` c WHERE `c`.`CONSTRAINT_TYPE` LIKE ? AND `c`.`TABLE_NAME`=? and `c`.`TABLE_SCHEMA`=? LIMIT 0,1';
PREPARE stmt FROM #n;
EXECUTE stmt USING #ctype,#tname,#dbname;
SELECT #cname;
SET #s = 'ALTER TABLE `documents` DROP FOREIGN KEY ?';
PREPARE stmtd FROM #s;
EXECUTE stmtd USING #cname;
END WHILE;
END $$
DELIMITER ;
CALL drop_foreign_key_documents;
The output of MySQL is:
#cname
documents_ibfk_13
ERROR 1064 (42000) at line 23: 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 '?' at line 1
Now I can imagine why it complains: the ALTER TABLE statement cannot use '?' because the constraint name is not part of a WHERE clause and so it cannot be replaced by a positional parameter. What I don't know is how to build a parametrized ALTER TABLE statement.
Obvious answer:
SET #s = CONCAT('ALTER TABLE `documents` DROP FOREIGN KEY ', #cname);
PREPARE stmtd FROM #s;
EXECUTE stmtd;