How to Use Multiple Parameters in a MySQL *Prepared* Stored Procedure - mysql

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

Related

Create stored procedure with specific schema in MYSQL and grant execute permission to user

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'#'%';

Dynamic query execute in MySQL

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?

passing table name in stored procedure

I am trying to figure out how I can pass part of a table name into a stored procedure and get it to work.
query is
DELIMITER $$
DROP PROCEDURE IF EXISTS vorpaldev.searchLogId2$$
CREATE DEFINER = 'root'#'%'
PROCEDURE vorpaldev.searchLogId2 (userId varchar(300))
BEGIN
SET userId = CONCAT("log", userId);
SET #statment = "Select * from #userId ";
PREPARE stmt FROM #statment;
SET #a = userId;
EXECUTE stmt USING #a;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER
;
I am using
CALL searchLogId2 (131)
to call the code
I want the end results to execute as
Select * from log131
Well! are you going to create seperate table for each user????????? If yes, that is really bad.
I don't know but may be this is your answer. Why dont you pass complete userId in parameter argument 'log131' as
BEGIN
SET #statment = concat('Select * from ',userId);
PREPARE stmt FROM #statment;
EXECUTE stmt USING userId;
DEALLOCATE PREPARE stmt;
END
this will remove overhead of concat

Using Prepared statement in Dynamic view

Here is my code
Drop procedure if exists test//
CREATE PROCEDURE test(IN woeid VARCHAR(15))
BEGIN
SET #w1 := woeid;
SET #sql = CONCAT('CREATE OR REPLACE VIEW temp
AS
SELECT *
FROM test_table gp
WHERE gp.name =', #w1);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
Delimiter ;
call test('ABCD');
I am getting error as
Error code: 1054. Unknown column 'ABCD' in 'where' clause
Please help.
It sounds as though you're needlessly using views, when some other approach would be more appropriate.
However, the reason it isn't working is that you haven't quoted your string literal, so the resulting SQL contains WHERE gp.name = ABCD whereas it at very least needs to be WHERE gp.name = 'ABCD'. You can use MySQL's QUOTE() function for this purpose, but it's better to parameterise the value:
DELIMITER //
DROP PROCEDURE IF EXISTS test//
CREATE PROCEDURE test(IN woeid VARCHAR(15))
BEGIN
SET #w1:=woeid, #sql:=CONCAT('
CREATE OR REPLACE VIEW temp AS
SELECT *
FROM test_table
WHERE name = ?
');
PREPARE stmt FROM #sql;
EXECUTE stmt USING #w1;
DEALLOCATE PREPARE stmt;
SET #w1:=NULL, #sql:=NULL;
END//
DELIMITER ;
CALL test('ABCD');

MySQL stored procedures - How to use parameter in FROM clause

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 ;