How to pass a subquery as a parameter to a MySQL procedure? - mysql

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 ;

Related

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?

Can I use a String as a WHERE CLAUSE

Can anybody help me with this JSP problem.
Im trying to update the database using code similar to this:
So, I have this on my Servlet:
String QueryCondition = "id = 1";
That will be passed to this stored procedure:
CREATE
DEFINER=`root`#`localhost`
PROCEDURE `storedprocedure_1`(QueryCondition TEXT)
BEGIN
UPDATE users SET name = 'John'
WHERE QueryCondition;
END
I was thinking if this is possible because the update always fail.
If this isn't possible can you recommend how can i do such thing
You can use it in a stored procedure but with a prepared statement.
Example:
DELIMITER //
CREATE
DEFINER=root#localhost
PROCEDURE storedprocedure_1(QueryCondition TEXT)
BEGIN
SET #query := CONCAT( 'UPDATE users SET name = \'John\' WHERE ',
QueryCondition );
PREPARE stmt FROM #query;
EXECUTE stmt;
DROP PREPARE stmt;
END;
//
DELIMITER ;

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

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

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