I'm trying to generate a dynamic SQL command stored in a LongText that will be executed in a stored procedure.
The code for the stored procedure looks like this:
DROP PROCEDURE IF EXISTS test.Dquery()
DELIMITER //
CREATE PROCEDURE test.Dquery()
BEGIN
DECLARE EXEC LONGTEXT DEFAULT '';
SET EXEC = CONCAT(
'
SELECT * FROM test.customers LIMIT 5;
');
PREPARE stmt FROM #EXEC;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
Getting an error in execution... Any ideas?
Related
Hello i have two db schemas "results" and "base". I am trying to create stored procedure in "results" database, and at the same time to give permission to user to run this procedure. What i did is:
DELIMITER //
DROP PROCEDURE IF EXISTS results.truncateResultsTable //
CREATE PROCEDURE results.truncateResultsTable(genId VARCHAR(255))
BEGIN
SET #genId = genId;
SET #q = CONCAT('TRUNCATE TABLE results_' , #genId);
PREPARE stmt FROM #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
GRANT EXECUTE ON FUNCTION results.truncateResultsTable TO 'lam_api'#'%';
END //
But getting this error
execute command denied to user 'lam_api'#'%' for routine 'results.truncateResultsTable
Any idea what i am doing wrong?
Here is right solution, i had couple of issues. GARANT part was misplaced, also was missing DELIMITER ;
DELIMITER //
DROP PROCEDURE IF EXISTS results.truncateResultsTable //
CREATE PROCEDURE results.truncateResultsTable(genId VARCHAR(255))
BEGIN
SET #genId = genId;
SET #q = CONCAT('TRUNCATE TABLE results_' , #genId);
PREPARE stmt FROM #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
GRANT EXECUTE ON PROCEDURE results.truncateResultsTable TO 'lam_api'#'%';
Although there are some good examples of multiple parameters being used in MySQL stored procedures, I have been unable to find a simple example that shows how to use them in a stored procedure that is prepared.
The code below returns 'Incorrect arguments to EXECUTE' when calling it using: `call test_parms('my report','example.com');
I've tried with and without '#' in front of the parameter names (just gives an unknown column error), and different variations of the code . What am I doing wrong?
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
set #REPORT=REPORT;
set #DOMAIN_NAME=DOMAIN_NAME;
PREPARE stmt FROM #sql;
EXECUTE stmt using #DOMAIN_NAME,#REPORT;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
The following section of the documentation will be helpful: 13.5.1. PREPARE Syntax.
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE PROCEDURE `test_parms`(`REPORT` VARCHAR(255), `DOMAIN_NAME` VARCHAR(255))
BEGIN
SET #`sql` := 'SELECT ? `DOMAIN_NAME`, ? `REPORT`';
SET #`REPORT` := `REPORT`;
SET #`DOMAIN_NAME` := `DOMAIN_NAME`;
PREPARE `stmt` FROM #`sql`;
EXECUTE `stmt` USING #`DOMAIN_NAME`, #`REPORT`;
DEALLOCATE PREPARE `stmt`;
END$$
DELIMITER ;
SQL Fiddle demo
UPDATE
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE PROCEDURE `test_parms`(`REPORT` VARCHAR(255), `DOMAIN_NAME` VARCHAR(255))
BEGIN
SELECT `DOMAIN_NAME` `DOMAIN_NAME`, `REPORT` `REPORT`;
END$$
DELIMITER ;
SQL Fiddle demo
Looks like I was unnecessarily setting user defined variables prior to execution, which was included in some of the stored procedure examples, but apparently doesn't work if the stored procedure is prepared.
To fix, Replace the following code:
set #REPORT=REPORT;
set #DOMAIN_NAME=DOMAIN_NAME;
PREPARE stmt FROM #sql;
EXECUTE stmt using #DOMAIN_NAME,#REPORT;
with this :
PREPARE stmt FROM #sql;
EXECUTE stmt;
So the corrected code looks like:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_parms`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Update
I ended up with the following which works with any user with privileges to execute procedures ('process' permission is not required like it is for the previous code) and works correctly on SQL Fiddle:
DROP PROCEDURE IF EXISTS `test_parms`//
CREATE PROCEDURE `test_parms`(REPORT VARCHAR(255),DOMAIN_NAME VARCHAR(255))
BEGIN
SET #sql = "Select #DOMAIN_NAME,#REPORT";
SET #DOMAIN_NAME=DOMAIN_NAME;
SET #REPORT=REPORT;
PREPARE stmt FROM #sql;
EXECUTE STMT;
DEALLOCATE PREPARE STMT ;
END//
SQL Fiddle - Updated Final
Is there a way I could pass a whole subquery as a parameter to my MySQL function and execute it under a condition? Something (but less faulty) like this..
delimiter //
create procedure myFunction (mySubquery)
begin
if (true) then
execute mySubquery;
end if;
/*rest of the action*/
end //
delimiter ;
You could pass the query as a good ol'string (a.k.a. VARCHAR) and prepare a statement from it:
CREATE PROCEDURE proc (param VARCHAR(100))
BEGIN
SET #query = param;
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #query = NULL;
END;
-- later on...
CALL proc('SELECT 1');
N.B. the ugly SET #query = param; workaround is required because "A statement prepared in stored program context cannot refer to (...) function parameters". (i.e. PREPARE stmt FROM param; is not allowed). Yuck.
You should add an error handler to such a procedure, because a broken query may (will eventually, as per Moore's law ;) be provided as a parameter. Your procedure should be prepared to handle this case gracefully.
try like this:
delimiter //
drop procedure if exists myFunction;
create procedure myFunction (mySubquery varchar(500))
begin
if (true) then
SET #mySubquery = mySubquery;
PREPARE stmt FROM #mySubquery;
EXECUTE stmt;
end if;
/*rest of the action*/
end //
delimiter ;
I have the following stored procedure:
DELIMITER ///
CREATE PROCEDURE tmp_test_proc(__TABLE__NAME varchar(255))
BEGIN
SELECT COUNT(*) FROM __TABLE__NAME;
END///
DELIMITER ;
I would like to select from the parameter __TABLE__NAME, but MySQL tells me there is no table __TABLE__NAME... So is there a way to use the value of the parameter in the from clause?
you cannot parameterized table names (as well as column names) by default, you need to create PreparedStatement for this,
DELIMITER ///
CREATE PROCEDURE tmp_test_proc(__TABLE__NAME varchar(255))
BEGIN
SET #sql = CONCAT('SELECT COUNT(*) FROM ', __TABLE__NAME);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END///
DELIMITER ;
What I want to do is,create a table in mysql by passing the table name as a parameter in the stored procedure.I'm using following code for stored procedure in mysql.
DELIMITER //
CREATE PROCEDURE createtable(IN tablename varchar(20))
BEGIN
SET #s=CONCAT('CREATE TABLE', tablename, '(month varchar(20))');
PREPARE stmt FROM #s;
EXECUTE stmt;
END //
and when i call it
CALL createtable('account');
I get the following error
You have an error in your SQL syntax; check the MySQL server version for the right syntax to us...
I don't know where I'm wrong..
You forgot the spaces before and after your table name. Try
DELIMITER //
CREATE PROCEDURE createtable(IN tablename varchar(20))
BEGIN
SET #s=CONCAT('CREATE TABLE ', tablename, ' (month varchar(20))');
PREPARE stmt FROM #s;
EXECUTE stmt;
END //