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);
That I need is
Save all of query in one table
query_id | sql_query
1 | select * from ms_user
2 | select * from ms_privileges
Create Procedure
this procedure will call
call my_procedure(query_id)
I tried the code below
DROP PROCEDURE IF EXISTS mp_test;
CREATE PROCEDURE global_procedire(IN id_query int(10));
BEGIN
SET #Query = 'SELECT sql_query from ms_query where query_id = id_query';
SET #Query = CONCAT(#Query);
PREPARE stmt FROM #Query;
EXECUTE stmt;
END
Imagine I have a table (Mysql myISAM) with a child->parent relationship (categories and multiple levels of subcategories)
+--------+---------+
| id |parent_id|
+--------+---------+
| 1 | null |
| 2 | 1 |
| 3 | 2 |
| 4 | 7 |
| 5 | 1 |
| 6 | 5 |
+--------+---------+
How would you find all children of some ID, like querying for id 1 would output :
2,5,3,6 ? (order has no importance)
So in other words, how to do a reverted children lookup on this parent_link ?
At the moment, I cycle in php and query for the parent_id, then again and concatenate all the results in a string while there are results, but this is so slow...
Ok, so thanks to Deepak code, I managed to write this, a bit shorter readable, it accepts a table as parameter and returns also the depth of the element.
DELIMITER $$
CREATE PROCEDURE get_children(IN V_KEY INT,IN SOURCETABLE VARCHAR(255))
proc:
BEGIN
DECLARE vid text;
DECLARE count int;
DROP TABLE IF EXISTS `temp_child_nodes`;
CREATE TEMPORARY TABLE temp_child_nodes(id int, depth int);
SET vid = V_KEY;
SET #val = '';
SET count = 0;
WHILE (vid is NOT NULL) DO
SET #sql = CONCAT("INSERT INTO temp_child_nodes(id,depth) SELECT id,'",count,"' from ",SOURCETABLE," where parent_id IN (",vid,")");
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET #tsql = CONCAT("SELECT GROUP_CONCAT(id) INTO #val from ",SOURCETABLE," where parent_id IN (", vid, ")");
PREPARE stmt2 FROM #tsql;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET vid = #val;
SET count = count + 1;
END WHILE;
#output data
SELECT * from temp_child_nodes;
END
$$
DELIMITER ;
create table my_table(
id int,
parent_id int
);
insert into my_table values
(1,null),
(2,1),
(3,2),
(4,7),
(5,1),
(6,5);
This stored procedure will get you all the children of any given id
DELIMITER $$
DROP PROCEDURE IF EXISTS get_children$$
CREATE PROCEDURE get_children(IN V_KEY INT)
proc:
BEGIN
DECLARE vid text;
declare oid text;
DECLARE count int;
CREATE TEMPORARY TABLE temp_child_nodes(
id int
);
SET vid = V_KEY;
INSERT INTO temp_child_nodes(id) SELECT id from my_table where parent_id = vid;
SELECT GROUP_CONCAT(concat("'",id,"'")) INTO oid from my_table where parent_id = vid;
SET vid = oid;
SET count = 0;
SET #val = '';
WHILE (vid is NOT NULL) DO
SET #sql = CONCAT("INSERT INTO temp_child_nodes(id) SELECT id from my_table where parent_id IN (",vid,")");
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET #tsql = CONCAT("SELECT GROUP_CONCAT(id) INTO #val from my_table where parent_id IN (", vid, ")");
PREPARE stmt2 FROM #tsql;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
SET vid = #val;
SET count = count + 1;
END WHILE;
#SELECT count;
SELECT * from temp_child_nodes;
#SELECT oid;
END
$$
DELIMITER ;
CALL get_children(1);
mysql> CALL get_children(1);
+------+
| id |
+------+
| 2 |
| 5 |
| 3 |
| 6 |
+------+
4 rows in set (0.22 sec)
Query OK, 0 rows affected (0.22 sec)
Here is the sqlfiddle demo for your query
http://sqlfiddle.com/#!2/ca90e/6
if there can be 'n' number of child then you need to use a stored procedure
I have following SP:
CREATE PROCEDURE sp_test
(
text_data varchar(50)
)
BEGIN
SET #var_query = CONCAT('SELECT * FROM sample_table WHERE col="',text_data,'"');
PREPARE stmt FROM #var_query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
I call this SP like so CALL sp_test('Screen size 4.3\"'). I get an error. Then if I check value of #var_query variable, this is how it looks.
+-------------------------------------------------------+
| #var_query |
+-------------------------------------------------------+
| SELECT FROM sample_table WHERE col="screen size 4.3"" |
+-------------------------------------------------------+
As you can see the escaped " is getting un-escaped. If I hit this select statement directly with escaped double-quotes, it runs fine. So it means concat is removing un-escaping the escaped characters. How to tackle this issue?
This is how it have to be:
SET #var_query = SELECT * FROM sample_table WHERE col=?';
SET #data = text_data;
PREPARE stmt FROM #var_query;
EXECUTE stmt USING #data;
DEALLOCATE PREPARE stmt;
while
Escape string gets un-escaped in mysql concat function
is correct and the only proper behavior.
I am stuck in Mysql today with the dynamic column name need in mysql select statement. Let me explain:
sql> select name1 from namescollection.
sql> select name2 from namescollection.
sql> select name3 from namescollection.
So namescollection table has three columns having name1, name2, name3
I would like to query this table in my stored procedure being 1,2,3 as dynamic and would be passed as a variable, but on the simple sql too when i query:
SELECT concat('name','1') FROM `namescollection`
name1 ----- name1 rather fetching name1 field's value.
Can any suggest on this, the right function i need to use rather concat though I know its right to output name1 when I am calling concat but I want to use it as column name.
What you can do is use a prepared statement within your stored procedure which will allow you to execute a string query:
As a simple example:
DELIMITER //
CREATE PROCEDURE selname (IN col VARCHAR(20))
BEGIN
SET #sql = CONCAT('SELECT ', col, ' FROM tbl');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
Test it out with this SQLFiddle Demo
Dynamic column name in store procedure Update statement :
DELIMITER //
CREATE DEFINER=`root`#`localhost` PROCEDURE `selname`()
BEGIN
declare cl int ;
declare clvalue int ;
set cl=1;
SET clvalue=1;
while cl < 4 DO
SET clvalue=clvalue*cl;
SET #sql = CONCAT('update test set col',cl, '=',clvalue,' where id=1');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set cl=cl+1;
end while;
END //
DELIMITER ;