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);
Related
CREATE PROCEDURE PRODUCT
(
IN products varchar(64)
)
BEGIN
SELECT COUNT(*) FROM t1 a
WHERE a.list in products;
END;
CALL PRODUCT('A');
Goal & Try
In PRODUCT procedure, it's ok when parameter is one(CALL PRODUCT('A') ). But when input is multiple like ('A','B','C','D'), it could not solve.
The index can be used. The list field is an index.
You can use FIND_IN_SET function.
WHERE FIND_IN_SET(a.list,products)>0;
Then call your procedure like below.
call PRODUCT('A,B,C,D');
If you have index on a.list you can try below.
CREATE PROCEDURE PRODUCT
(
IN products varchar(64)
)
BEGIN
SET #sql = concat('SELECT COUNT(*) FROM t1 a WHERE a.list in(','''',REPLACE(products,',',''','''),'''',')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
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
I'm getting a syntax error in my stored procedure when trying to use a variable as a reference to a tables column.
BEGIN
SET #mycolumn = (SOME SELECT STATEMENT RETURNING MY COLUMN);
SELECT a.#mycolumn FROM mytable as a;
END
Question: What is wrong with my syntax?
It looks like you're trying to do dynamic SQL. Here is one way to do it:
BEGIN
SET #mycolumn = (SOME SELECT STATEMENT RETURNING MY COLUMN);
DECLARE #sql varchar(20000);
SET #sql = CONCAT('SELECT a.', #mycolumn, ' FROM mytable as a';
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Jordan,
You might need to use table variable or Dynamic SQL for this.
Here is how I do this with table variable.
Declare #table as table (columnName dataType.
Insert into #table
SOME SELECT STATEMENT RETURNING YOUR COLUMN
Results by running the below query:-
SELECT * FROM #table
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.
1)Below is the code I'm trying for a procedure where I need to compare the count from two different tables. (tbl1 and tbl2 are in parameters to be passed).
But in the above code the values for 'a' and 'b' are set as statements. I need the resultant value(count) from the two statements to compare in the 'IF' condition.
declare a integer;
declare b integer;
set #a:=concat('select count(*) from ', tbl1);
/*PREPARE stmt1 FROM #a;
execute stmt1;
deallocate PREPARE stmt1;*/
set #b:= concat('select count(*) from ', tbl2);
/*PREPARE stmt2 FROM #b;
execute stmt2;
deallocate PREPARE stmt2;*/
if
#a=#b
then
select 1;
else
select 2;
end if;
2) Actually where I am facing a problem to set 'tbl1' and 'tbl2' as parameters in procedure.
The below code works fine if the table names are given directly, but i need them as parameters.
CREATE PROCEDURE myproc (in tbl1 varchar(50), in tbl2 varchar(50))
declare a integer;
declare b integer;
set #a:=(select count(*) from tbl1);
/*PREPARE stmt1 FROM #a;
execute stmt1;
deallocate PREPARE stmt1;*/
set #b:= (select count(*) from tbl2);
/*PREPARE stmt2 FROM #b;
execute stmt2;
deallocate PREPARE stmt2;*/
if
#a=#b
then
select 1;
else
select 2;
end if;
Hope anyone out there can help me with the solution.
As mentioned in the comments above, it is likely that you shouldn't be doing this at all... but, for what it's worth:
SET #sql := CONCAT('SELECT (
SELECT COUNT(*) FROM `',REPLACE('`','``',tbl1),'`
) = (
SELECT COUNT(*) FROM `',REPLACE('`','``',tbl2),'`
);');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #sql := NULL;
REPLACE() has been used to try and avoid SQL injection (it's somewhat crude, but it's the best one can do without further information).