Explain the stored procedure described below - mysql

CREATE DEFINER=`root`#`localhost` PROCEDURE `get_plan_images`(
_list varchar(2000)
)
BEGIN
SET #LIST=_list;
set #sql = concat('SELECT plan_id, plan_image
FROM ibuild.plan_images
where plan_id in (', #LIST , ')');
PREPARE q FROM #sql;
execute q;
END
What does concat do here? And what does this statement means PREPARE q FROM #sql;

CONCAT simply merges two or more pieces of text together. In the example above, #LIST contains a list of ids passed in to the procedure. After the CONCAT, #sql becomes a string that contains something like:SELECT plan_id, plan_image FROM ibuild.plan_images where plan_id in (1,2,3)
See here: MySQL CONCAT Function
The PREPARE statement just gives the statement a name so you can execute it. See here: MySQL PREPARE

Related

How to set the result of a query as a queryable table?

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

Stored procedure output variable

I am trying to run a procedure that takes a parameter 'table' for the query, and result as the output parameter. However, it shows as undeclared variable: result
I have doubled checked that no spelling mistake but still have no idea how it happened. Would someone please provide some help or guidance
CREATE DEFINER=`root`#`localhost` PROCEDURE `Function`(IN table varchar(10), OUT result varchar (10))
BEGIN
SET #q = CONCAT ('
Select `field` from `',table,'` into result limit 1;');
PREPARE stmt from #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Try:
...
-- SET #q = CONCAT ('Select `field` from `',table,'` into result limit 1;');
SET #`q` := CONCAT('SELECT `der`.`field`
FROM (SELECT `field` FROM `', `table`, '` LIMIT 1) `der`,
(SELECT #`result` := NULL) `init`
INTO #`result`;');
PREPARE `stmt` from #`q`;
EXECUTE `stmt`;
SET `result` := #`result`;
DEALLOCATE PREPARE `stmt`;
...
It is important to indicate the difference between 9.4. User-Defined Variables and routine parameters 13.1.15. CREATE PROCEDURE and CREATE FUNCTION Syntax, are different variables.
SQL Fiddle demo

how to define a stored procedures which accepts 2 parameteres

I´m trying to define a stored procedures which accepts 2 parameteres , one would be the table column which has to be equal with the second parameter i will provide.
Code :
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `selectUserByField`(IN _field varchar(150) , IN _value varchar(150))
BEGIN
SET #sql = CONCAT('SELECT * FROM Users WHERE', _field, '=' ,_value);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
The thing is that i don´t know how to provide the _value param as a string. If i run it like this i get a Mysql 1064 near ´=myEmail´( params where ´userEmail´,´myEmail´). Thanks !
In your below code, you are missing a space after WHERE. It should be like below; give a space after WHERE and in =
SET #sql = CONCAT('SELECT * FROM Users WHERE ', _field, ' = ' ,_value);

IN Clause dont work in MySQL for me

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 (?)'

use a variable for table name in mysql sproc

I'm trying to pass a table name into my mysql stored procedure to use this sproc to select off of different tables but it's not working...
this is what I"m trying:
CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100)
)
BEGIN
SELECT * FROM #TableName;
END
I've also tried it w/o the # sign and that just tells me that TableName doesn't exist...which I know :)
SET #cname:='jello';
SET #vname:='dwb';
SET #sql_text = concat('select concept_id,concept_name,',#vname,' from enc2.concept a JOIN enc2.ratings b USING(concept_id) where concept_name like (''%',#cname,'%'') and 3 is not null order by 3 asc');
PREPARE stmt FROM #sql_text;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
An extra bit that caused me problems.
I wanted to set the table name and field dynamically in a query as #kyle asked, but I also wanted to store the result of that query into a variable #a within the query.
Instead of putting the variable #a into the concat literally, you need to include it as part of the string text.
delimiter //
CREATE PROCEDURE removeProcessed(table_name VARCHAR(255), keyField VARCHAR(255), maxId INT, num_rows INT)
BEGIN
SET #table_name = table_name;
SET #keyField = keyField;
SET #maxId = maxId;
SET #num_rows = num_rows;
SET #sql_text1 = concat('SELECT MIN(',#keyField,') INTO #a FROM ',#table_name);
PREPARE stmt1 FROM #sql_text1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
loop_label: LOOP
SET #sql_text2 = concat('SELECT ',#keyField,' INTO #z FROM ',#table_name,' WHERE ',#keyField,' >= ',#a,' ORDER BY ',#keyField,' LIMIT ',#num_rows,',1');
PREPARE stmt2 FROM #sql_text2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
...Additional looping code...
END LOOP;
END
//
delimiter ;
So in #sql_text1 assign the result of the query to #a within the string using:
') INTO #a FROM '
Then in #sql_text2 use #a as an actual variable:
,' WHERE ',#keyField,' >= ',#a,' ORDER BY '
It depends on the DBMS, but the notation usually requires Dynamic SQL, and runs into the problem that the return values from the function depend on the inputs when it is executed. This gives the system conniptions. As a general rule (and therefore probably subject to exceptions), DBMS do not allow you to use placeholders (parameters) for structural elements of a query such as table names or column names; they only allow you to specify values such as column values.
Some DBMS do have stored procedure support that will allow you to build up an SQL string and then work with that, using 'prepare' or 'execute immediate' or similar operations. Note, however, that you are suddenly vulnerable to SQL injection attacks - someone who can execute your procedure is then able to control, in part, what SQL gets executed.