1

Imagine that I have several dynamic table names such as :

select table_name
from INFORMATION_SCHEMA.TABLES
where table_name like 'ifhcraw%';
ifhcraw_2016_03_25_13
ifhcraw_2016_03_26_19
ifhcraw_2016_03_28_2

And I don't found any rule on names. To find last edited table I have just select last modified table with query :

select table_name
from INFORMATION_SCHEMA.TABLES
where table_name like 'ifhcraw%' and
      update_time = (select max(update_time)
                     from INFORMATION_SCHEMA.TABLES
                     where table_name like 'ifhcraw%');

Now the purpose all of this step to get data from table_name. I have tried to use variables , however it was failed. For example :

SET @query1 := 'select table_name
                from INFORMATION_SCHEMA.TABLES
                where table_name like \'ifhcraw%\' and
                update_time = (select max(update_time)
                               from INFORMATION_SCHEMA.TABLES
                               where table_name like \'ifhcraw%\') ';
SET @query2 := concat('select *
                       from ', @query1);
PREPARE stmt from @query2;
execute stmt;

Please help to solve issue.

wchiquito
  • 16,177
  • 2
  • 34
  • 45
Javid
  • 47
  • 2
  • 8
  • From the very first sentence, this all just seems so wrong. – Strawberry Apr 01 '16 at 10:30
  • Can you use merge or partitioned tables instead of tables with similar names? If not, then what was the exact error message you encountered while running the prepared statement? – Shadow Apr 01 '16 at 10:47
  • Sorry, but I ma not good with SQL. No, I can't. – Javid Apr 01 '16 at 11:38
  • I have got message: SQL (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select table_name from INFORMATION_SCHEMA.TABLES where table_name like 'ifhcraw%' at line 1 */ – Javid Apr 01 '16 at 11:38
  • `SET @query2 := concat('select * from ', /*@query1:*/'select table_name ...');`. Try `PREPARE stmt from @query1;`. – wchiquito Apr 01 '16 at 12:33

1 Answers1

3

Try:

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.11    |
+-----------+
1 row in set (0.00 sec)

mysql> DROP TABLE IF EXISTS `ifhcraw_2016_03_25_13`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS `ifhcraw_2016_03_26_19`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS `ifhcraw_2016_03_28_2`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `ifhcraw_2016_03_25_13` (
    ->   `id` INT
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `ifhcraw_2016_03_26_19` (
    ->   `id` INT
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `ifhcraw_2016_03_28_2` (
    ->   `id` INT
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> SET @`TABLE_NAME` := NULL;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT `TABLE_NAME` INTO @`TABLE_NAME`
    -> FROM `INFORMATION_SCHEMA`.`TABLES`
    -> WHERE `TABLE_NAME` LIKE 'ifhcraw%' AND
    ->       `UPDATE_TIME` = (SELECT MAX(`UPDATE_TIME`)
    ->                        FROM `INFORMATION_SCHEMA`.`TABLES`
    ->                        WHERE `TABLE_NAME` LIKE 'ifhcraw%'
    ->                       );
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> SELECT @`TABLE_NAME`;
+---------------+
| @`TABLE_NAME` |
+---------------+
| NULL          |
+---------------+
1 row in set (0.00 sec)

mysql> SET @`qry` := IF(@`TABLE_NAME` IS NULL,
    ->                  'SELECT NULL',
    ->                  CONCAT('SELECT * FROM ', @`TABLE_NAME`));
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE `stmt` FROM @`qry`;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE `stmt`;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)

mysql> DEALLOCATE PREPARE `stmt`;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `ifhcraw_2016_03_26_19`
    ->   (`id`)
    -> VALUES
    ->   (1);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT `TABLE_NAME` INTO @`TABLE_NAME`
    -> FROM `INFORMATION_SCHEMA`.`TABLES`
    -> WHERE `TABLE_NAME` LIKE 'ifhcraw%' AND
    ->       `UPDATE_TIME` = (SELECT MAX(`UPDATE_TIME`)
    ->                        FROM `INFORMATION_SCHEMA`.`TABLES`
    ->                        WHERE `TABLE_NAME` LIKE 'ifhcraw%'
    ->                       );
Query OK, 1 row affected (0.00 sec)

mysql> SELECT @`TABLE_NAME`;
+-----------------------+
| @`TABLE_NAME`         |
+-----------------------+
| ifhcraw_2016_03_26_19 |
+-----------------------+
1 row in set (0.00 sec)

mysql> SET @`qry` := IF(@`TABLE_NAME` IS NULL,
    ->                  'SELECT NULL',
    ->                  CONCAT('SELECT * FROM ', @`TABLE_NAME`));
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE `stmt` FROM @`qry`;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE `stmt`;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

mysql> DEALLOCATE PREPARE `stmt`;
Query OK, 0 rows affected (0.00 sec)

UPDATE

Care should be taken when there are two or more tables that match the criteria, will fail as follows:

mysql> INSERT INTO `ifhcraw_2016_03_26_19`
    ->   (`id`)
    -> VALUES
    ->   (1);
Query OK, 1 row affected (0,00 sec)

mysql> INSERT INTO `ifhcraw_2016_03_28_2`
    ->   (`id`)
    -> VALUES
    ->   (1);
Query OK, 1 row affected (0,00 sec)

mysql> SELECT `TABLE_NAME`
    -> FROM `INFORMATION_SCHEMA`.`TABLES`
    -> WHERE `TABLE_NAME` LIKE 'ifhcraw%' AND
    ->       `UPDATE_TIME` = (SELECT MAX(`UPDATE_TIME`)
    ->                        FROM `INFORMATION_SCHEMA`.`TABLES`
    ->                        WHERE `TABLE_NAME` LIKE 'ifhcraw%'
    ->                       );
+-----------------------+
| TABLE_NAME            |
+-----------------------+
| ifhcraw_2016_03_26_19 |
| ifhcraw_2016_03_28_2  |
+-----------------------+
2 rows in set (0,00 sec)

mysql> SELECT `TABLE_NAME` INTO @`TABLE_NAME`
    -> FROM `INFORMATION_SCHEMA`.`TABLES`
    -> WHERE `TABLE_NAME` LIKE 'ifhcraw%' AND
    ->       `UPDATE_TIME` = (SELECT MAX(`UPDATE_TIME`)
    ->                        FROM `INFORMATION_SCHEMA`.`TABLES`
    ->                        WHERE `TABLE_NAME` LIKE 'ifhcraw%'
    ->                       );
ERROR 1172 (42000): Result consisted of more than one row

You should handle the case as you deem appropriate.

wchiquito
  • 16,177
  • 2
  • 34
  • 45