I have the following stored procedure. The idea is to get a list of databases and execute an sql statement.
DELIMITER $$
CREATE PROCEDURE updateMySQL (
IN theSQL varchar(4000)
)
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE theDatabases varchar(100) DEFAULT "";
-- declare cursor for employee email
DEClARE curDatabase
CURSOR FOR
SELECT schema_name FROM information_schema.schemata where SCHEMA_NAME = 'mydb' order by 1;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN curDatabase;
getDatabase: LOOP
FETCH curDatabase INTO theDatabases;
IF finished = 1 THEN
LEAVE getDatabase;
END IF;
-- build email list
-- SET emailList = CONCAT(theDatabases,";",emailList);
SET #sql:=CONCAT('USE ',#curDatabase);
PREPARE dynamic_statement FROM #SQL;
EXECUTE dynamic_statement;
PREPARE dynamic_statement FROM #theSQL;
EXECUTE dynamic_statement;
END LOOP getDatabase;
CLOSE curDatabase;
END$$
DELIMITER ;
I am attempting to execute the stored procedure like this,
SET #theSQL = 'ALTER VIEW `Reports` AS
SELECT DISTINCT
`tableA`.`Id` AS `Id`,
`tableA`.`letterId` AS `letterId`
FROM
`mytable` `tableA`
ORDER BY 1';
call updateMySQL(#theSQL);
EDIT There was an error on executing the procedure,
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
I am using mysql 8.0.17
Investigate carefully MySQL 8.0 Reference Manual / SQL Statements / Prepared Statements, the section "SQL Syntax Allowed in Prepared Statements".
This section claims FULL list of statements which are allowed in Prepared statements. ALTER VIEW is NOT listed. So it is NOT allowed.
Use DROP VIEW and CREATE VIEW instead.
Always receive and investigate all error messages.
You should change this part
SET #sql:=CONCAT('USE ',#curDatabase);
PREPARE dynamic_statement FROM #SQL;
EXECUTE dynamic_statement;
PREPARE dynamic_statement FROM #theSQL;
EXECUTE dynamic_statement;
to this:
SET #sql:=CONCAT('USE ',#curDatabase);
PREPARE dynamic_statement FROM #SQL;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement; /* don't forget to deallocate */
/* there's a difference between the variables #theSQL and theSQL (your parameter) */
/* IIRC prepare statements need user defined variables or a syntax error occurs. Therefore I simply assign the parameter to a user-defined variable */
SET #theSQL = theSQL;
PREPARE dynamic_statement FROM #theSQL;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
Read more about user-defined variables here: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html
Here the differences are explained: https://stackoverflow.com/a/1010042/447489
When you don't initialize them, their content is just NULL. Since there's a difference between user-defined variables and local variables (and also your parameter variable), your current solution did nothing.
Related
I try to execute a variable query within a custom mysql function, here's the script :
DELIMITER $
CREATE FUNCTION is_present(in_id BIGINT, in_table_name VARCHAR(255)) RETURNS BIT
BEGIN
DECLARE stm VARCHAR(255);
DECLARE result BIT DEFAULT 0;
SET stm := CONCAT('SELECT IF(COUNT(*), 1, 0) INTO result FROM', in_table_name, 'WHERE id=? LIMIT 1');
PREPARE query FROM stm;
EXECUTE query USING in_id;
DEALLOCATE PREPARE query;
RETURN result;
END $
DELIMITER ;
Mysql warns me about the syntax :
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 'stm; EXECUTE query USING in_id; DEALLOCATE PREPARE query;
RETURN result; ' at line 9
I think you are missing a semicolon before var name:
PREPARE query FROM :stm;
I use mysql workbench 6.2 for my database.
I created procedure to execute query string, But it error "syntax error unexpected" for variable 'declare #str varchar(2000)'. i try remove '#' in variable , but it is not effective in line 'PREPARE stmt FROM str;'. it notify error "unexpected str"
this is my code:
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_procedure`()
BEGIN
declare #str varchar(2000) DEFAULT '';
set #str = 'select * from category;';
PREPARE stmt FROM #str;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Session variables are not declared. You do not need (and cannot do)
DECLARE #str varchar(2000) DEFAULT '';
only the set you already have is necessary
SET #str = 'select * from category;';
As an aside, it is best to name the session variables in situations like this something unique (in case the connection calling the procedure is already using the simple name for something else).
The error mysql is throwing is
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
My using phpmyadmin to wreite procedures.
and my stored procedure is
BEGIN
DECLARE page_limit int(100);
DECLARE page_no VARCHAR(100);
DECLARE rstarts int(100) DEFAULT 1;
DECLARE rends int(100) DEFAULT 15;
DECLARE query varchar(255) ;
set query = ' select brandid from brandinfo limit #rstarts,#rends';
PREPARE stmt FROM #query;
set rstarts = 15;
set rends =1;
EXECUTE stmt using #rstarts,#rends;
DEALLOCATE PREPARE stmt;
END
Declared variables and variables beginning with # are two different stories. Read about user defined variables (the ones with #).
DELIMITER $$
CREATE PROCEDURE your_procedure_name()
BEGIN
SET #rstarts = 1;
SET #rends = 15;
set #query = 'select brandid from brandinfo limit ?, ?';
PREPARE stmt FROM #query;
EXECUTE stmt using #rstarts, #rends;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
Also in your query string you want to use ? as parameters, not the variable names. And you might miss on setting the delimiter to something different than ;
I'm wrestling with MySQL stored procedures, and the PREPARE / EXECUTE statement pair. I'm attempting to run the (simplified) code below in order to create a stored procedure that will encapsulate several queries into a transaction with rollback. I continue to get
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 'goodID;
If I remove the transaction and handlers all is well with the code. If I remove the EXECUTEstatement the procedure can be created.
What am I missing here?
DELIMITER $$
USE `casc`$$
DROP PROCEDURE IF EXISTS `sp_T_MergeMemberIDs`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_T_MergeMemberIDs`(IN goodID VARCHAR(8), OUT param_sp_success TINYINT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK;
START TRANSACTION;
SET param_sp_success = 0;
SET #SQL=
"SELECT * FROM member
WHERE memberID = ?";
PREPARE stmt FROM #SQL;
EXECUTE stmt USING goodID;
-- queries executed here using the same parameter
-- omitted for simplicity
SET param_sp_success = 1;
COMMIT;
END$$
As far as I remember, you need to use session user variable in execute ...using :
...
PREPARE stmt FROM #SQL;
SET #tmp_var = goodID;
EXECUTE stmt USING #tmp_var;
...
I am getting syntax error on runnning this. Is it possible to use variables with limit without using concat function?
CREATE PROCEDURE SP(_start INT,_end INT)
BEGIN
DECLARE _qry VARCHAR(500) DEFAULT CONCAT('select * from tbl limit ',_start,_end);
PREPARE stmt FROM _qry;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Error is
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 '_qry;
EXECUTE stmt;
You missed , before the offset.
CREATE PROCEDURE SP(_start INT,_end INT)
BEGIN
DECLARE _qry VARCHAR(500) DEFAULT CONCAT('select * from tbl limit ', _start, ',', _end);
PREPARE stmt FROM _qry;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
I think you have to change the DEFAULT DELIMITER first and adding PARAMETER DIRECTION before creating the STORED PROCEDURE.
There are good reasons to use prepared statements:
1. ) Save on query parsing
2.) Save on data conversion and copying
3.) Avoid SQL Injection
4.) Save memory on handling blobs
There are also drawbacks and chewats of using prepared statements:
1.) Query cache does not work
2.) Extra server round trip required if statement used only once
3.) Not all statements can be prepared. So you can’t use prepared API
exclusively you’ll need to fall back to normal API for some statements
4.) Newer and sometimes buggy code. I had a lot of problems with PHP
prepared statements. It is getting better but still it is less mature
than standard API
5.) You can’t use placeholders in place of all identifiers. For example you
can’t use them for table name. In certain version it even does not work for
LIMIT boundaries
6.) Inconvenient list handling. Unlike in for example PEAR emulated prepard
statements there is no nice way to pass list of values to IN
7.) Harder tracing. Logs were now fixed to include full statement text not
only “Execute” but in SHOW INNODB STATUS you would still see statements
without actual values – quite inonvenient for analyses.
try this one:
UPDATE 1
DELIMITER $$
CREATE PROCEDURE SP(IN _start INT,IN _end INT)
BEGIN
SET #iQuery = CONCAT('select * from tbl limit ', _start, ',', _end);
PREPARE stmt FROM #iQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
MySQL Syntax for Prepared Statements
delimiter //
drop procedure if exists SP //
create procedure SP(_start int,_end int)
begin
declare _qry varchar(500);
set #_qry = 'select * from tbl limit ?, ?';
set #start = _start;
set #end = _end;
prepare stmt from #qry;
execute stmt using #start, #end;
deallocate prepare stmt;
end; //
delimiter ;
call SP(1,2);