I need to create a 'select' mysql procedure that will accept multiple parameters, inline with this the procedure will select to other tables
Objective
Stored procedure must accept multiple parameters
Using the multiple parameters, procedure should select on table_a, table_b and table_c
Currently i am using this code (it accepts multiple parameter but I don't know how to modify it so it would do another select on table_b and table_c)
DELIMITER //
CREATE PROCEDURE select_multiple_object(IN user_ids VARCHAR(65535))
BEGIN
SET #query = CONCAT ('SELECt * FROM table_a WHERE userid IN (',user_ids,')');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
What I really want to achieve is something like this:
DELIMITER //
CREATE PROCEDURE select_multiple_object(IN user_ids VARCHAR(65535))
BEGIN
SET #query = CONCAT ('
SELECt * FROM table_a WHERE userid IN (',user_ids,');
SELECt * FROM table_b WHERE userid IN (',user_ids,');
SELECt * FROM table_c WHERE userid IN (',user_ids,');
');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
CALL select_multiple_object('1,2,3')
Assemble your MySQL query first, then send the query, similar to the following:
$parameter = "user_ids";
$table = "table_a";
$query = 'SELECT * FROM ' . $parameter . ' WHERE userid IN (",' . $parameter . ',")';
$result = mysql_query($query);
To input multiple parameters, simply use a loop to repeat this process as needed.
Related
I am trying to use the result of a query as a table.
This query works fine:
SELECT date, number FROM `table_A`
The query below as well --> its result is table_B as a string of character not the table itself
SELECT nametable FROM `list_repository` WHERE id=1
But the combined one does not:
SELECT date, number FROM (SELECT nametable FROM `list_repository` WHERE id=1) A
I expect the resulting query to be
SELECT date, number FROM `table_B`
I tried to set a variable but it does not work either:
DECLARE x VARCHAR(150) ;
SET table=( SELECT `nametable` FROM `list_repository` WHERE id=1);
SELECT * from `table`. But it would not work
Thank you for your help!
Identifiers (db, table, column names etc) in SQL are static. Therefore you can't populate them at run-time. But you can build a query as a string and execute it via dynamic SQL. Something along the lines of
SET #sql = NULL;
SELECT CONCAT("SELECT * FROM ", nametable)
INTO #sql
FROM list_repository
WHERE id = 1;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
An example of wrapping it up into a stored procedure
DELIMITER //
CREATE PROCEDURE sp1 (IN id INT)
BEGIN
SET #sql = NULL;
SELECT CONCAT("SELECT * FROM ", nametable)
INTO #sql
FROM list_repository
WHERE id = id;
SELECT #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
And then invoking it
CALL sp1(1);
I am passing my parameter as 'Suburbun','Indigo' to retrieve records matching both Campaigns in below Stored Procedure created in MySql.
CREATE PROCEDURE `DemoSP`(Campaign VARCHAR(3000))
BEGIN
SET #query = CONCAT('Select * from vicidial_log WHERE campaign_id IN (?)');
PREPARE stmt FROM #query;
SET #CampaignID = Campaign;
EXECUTE stmt USING #CampaignID;
DEALLOCATE PREPARE stmt;
END;
It Doesn't give any rows!
But when i pass only 'Suburbun' in SP, it gives 6 Rows!
Where am i going wrong?
--Answer !
I tried as Lee Fentress commented in http://www.poolofthought.com/index.php/2008/12/28/a-comma-seperated-list-as-parameter-to-mysql-stored-procedure/ and peterm answer reflected similar coding,
It worked!
Thanks, but i find this negative mark as compared to SQL Server.
Gee, Thank you Guys!!
You won't be able to use USING in this case. You can just build the full query sting and execute it without parameters
DELIMITER $$
CREATE PROCEDURE DemoSP(Campaign VARCHAR(3000))
BEGIN
SET #query = CONCAT('SELECT * FROM vicidial_log WHERE campaign_id IN (', Campaign, ')');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Note: make sure that delimited values that you pass in Campaign are properly quoted (like you said they are) and quotes in values, if there is any, are escaped.
Here is SQLFiddle demo
Try this:
There is no need to use PREPARE STATEMENT. You can get the result using FIND_IN_SET() function
SELECT * FROM vicidial_log WHERE FIND_IN_SET(campaign_id, Campaign)
try this
"Select * from vicidial_log WHERE campaign_id IN ('?')"
instead of
'Select * from vicidial_log WHERE campaign_id IN (?)'
I am trying to create a stored procedure in mysql which creates a new table on every request copies the content from another table and extracts the required data and finally drops the table. The stored procedure is quite large so I cant have EXECUTE after every query and thus I am trying to execute the query all together in a semicolon separated format. But on final execution I get Error Code: 1064.
Is the approach I am trying possible, or is there a better approach.
SET tableName = (SELECT CONCAT("table",(UNIX_TIMESTAMP(NOW()))));
SET #tquery =CONCAT('CREATE TABLE `',tableName,'` (select pt.* from post_table pt join on user u on pt.user_id=u.id where pt.client="client",pt.group="group");');
SET #tquery = CONCAT(#tquery,' SELECT * FROM ',tableName,';');
SET #tquery = CONCAT(#tquery,' DROP TABLE ',tableName,';');
PREPARE stmt FROM #tquery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
No, it is not possible. PREPARE / EXECUTE stmt can execute only one query at a time, many statements cannot be combined. See documentation: http://dev.mysql.com/doc/refman/5.0/en/prepare.html
... a user variable that contains the text of the SQL statement. The text must represent a single statement, not multiple statements.
Anyway, to simplify your code I would create a simple procedure:
CREATE PROCEDURE exec_qry( p_sql varchar(100))
BEGIN
SET #tquery = p_sql;
PREPARE stmt FROM #tquery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
/
and I would call this procedure in the main procedure, in this way:
CALL exec_qry( 'CREATE TABLE t2 AS SELECT * FROM test');
CALL exec_qry( 'SELECT * FROM t2');
CALL exec_qry( 'SELECT count(*) FROM t2');
CALL exec_qry( 'SELECT avg(x) FROM t2');
CALL exec_qry( 'DROP TABLE t2');
Take a look at a demo: http://www.sqlfiddle.com/#!2/6649a/6
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
How do I cache dynamic query from store procedure?
Right now I have created my store procedure like this :
CREATE PROCEDURE usp_MyProcedure (
IN UserID INT,
....
)
BEGIN
SET #sqlQuery = CONCAT("SELECT Name From Users WHERE UserID > ", UserID, " AND UserID IN ( SELECT UserID FROM OtherTable WHERE UserID = ", UserID, " ) Order by Name")
PREPARE stmt FROM #sqlQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
But this kind of query does not cached. so, every time it gets more time to execute/process query.
Now I have tried some other method like this:
CREATE PROCEDURE usp_MyProcedure (
IN UserID INT,
....
)
BEGIN
SET #UserID = UserID;
SET #sqlQuery = "SELECT Name From Users WHERE UserID > ? AND UserID IN ( SELECT UserID FROM OtherTable WHERE UserID = ? ) Order by Name";
PREPARE stmt FROM #sqlQuery;
EXECUTE stmt #UserID, #UserID; -- here i passed same variable twice.
DEALLOCATE PREPARE stmt;
END;
In the above case I have to pass same variable (#UserID) twice, because it is used 2 times in my query. but this job is very hectic in long or complex query. so, how do I avoid this?
One another method I tried as follows:
CREATE PROCEDURE usp_MyProcedure (
IN UserID INT,
....
)
BEGIN
SET #UserID = UserID;
SET #sqlQuery = "SELECT Name From Users WHERE UserID > #UserID AND UserID IN ( SELECT UserID FROM OtherTable WHERE UserID = #UserID ) Order by Name";
PREPARE stmt FROM #sqlQuery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
But above query again does not cached. so, execution time is very long. and this type of variable declared as session global variable has may be conflict with another store procedure's variable. because I have call store procedure within this store procedure and variable name should be same in another store procedure.
So, let me know what is the best solution for the same.
Thanks.
Sorry just posted a mistaken one,
DELIMITER //
CREATE PROCEDURE yourprocedurenamehere(IN state CHAR(2))
BEGIN
SET #mystate = state;
SET #sql = CONCAT('SELECT * FROM BLABLABLA WHERE BLA = ?');
PREPARE stmt FROM #sql;
EXECUTE stmt USING #mystate;
END;
//
Sorry pal, just edited my code hahaha I got this wrong
A short answer is that there is no way to do it. In theory, you could identify prepared statement name with sha1(prepared statement query text), and use this as a statement handle. But there is no way to dynamically execute a statement which name is stored in a variable or in a table: EXECUTE itself is not allowed in Dynamic SQL query text.
A different question is whether you need a Dynamic SQL in your example at all, it seems like a standard SQL stored procedure parameterized with input parameters could do just fine.