10

I want to output data from every table that contains a first_name column. I put together the following procedure, but in my loop, mysql interprets the table name literally instead of evaluating the variable table_name. What's the fix?

delimiter //

drop procedure if exists hunt //
create procedure hunt()
begin
    DECLARE done int default false;
    DECLARE table_name CHAR(255);

    DECLARE cur1 cursor for SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_SCHEMA = "wholesale_production" and COLUMN_NAME LIKE "%first%" ;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    open cur1;

    myloop: loop
        fetch cur1 into table_name;
        if done then
            leave myloop;
        end if;
        select * from `wholesale_production`.table_name where created_at >= '2012-10-01';
    end loop;

    close cur1;
end //

delimiter ;

call hunt();
JellicleCat
  • 26,352
  • 22
  • 102
  • 152

4 Answers4

16

Try this:

delimiter //

drop procedure if exists hunt //
create procedure hunt()
begin
    DECLARE done BOOL default false;
    DECLARE tablename CHAR(255);

    DECLARE cur1 cursor for SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_SCHEMA = "wholesale_production" and COLUMN_NAME LIKE "%first%" ;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    open cur1;

    myloop: loop
        fetch cur1 into tablename;
        if done then
            leave myloop;
        end if;
        set @sql = CONCAT('select * from `wholesale_production`.', tablename, ' where created_at >= ''2012-10-01''');
        prepare stmt from @sql;
        execute stmt;
        drop prepare stmt;
    end loop;

    close cur1;
end //

delimiter ;

call hunt();
Regular Jo
  • 4,552
  • 3
  • 19
  • 37
Ross Smith II
  • 11,414
  • 1
  • 36
  • 41
  • 1
    I have a similar problem. If I don't care about filtering the table name to be `LIKE '%first%'`, can I just use `SHOW TABLES` instead of `SELECT TABLE_NAME ...`? – Kal Nov 05 '13 at 02:10
  • 4
    table_name is a reserved name. should be changed to a different name. – Dominic Sep 24 '14 at 12:35
  • 1
    SELECT distinct TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = "wholesale_production" ; – Lennart Rolland May 04 '18 at 22:00
1

a little edit of the above to itertate ahtoug all the tables and select them.

delimiter //
drop procedure if exists hunt //
create procedure hunt()
begin
    DECLARE done int default false;
    DECLARE table_name CHAR(255);

    DECLARE cur1 cursor for SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
                  WHERE table_schema ='mbu4u';
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    open cur1;
       myloop: loop
        fetch cur1 into table_name;
        if done then
            leave myloop;
        end if;
        set @sql = CONCAT('select * from `mbu4u`.',table_name);
        prepare stmt from @sql;
        execute stmt;
        drop prepare stmt;
    end loop;

    close cur1;
end //

delimiter //
Daniel Adenew
  • 7,255
  • 7
  • 54
  • 75
0

table_name is a reserved token use another variable name in "DECLARE table_name CHAR(255);"

Pau Dominguez
  • 151
  • 1
  • 1
  • 8
-3

in cur1 you are using TABLE_NAME there try using a real name of the table

dev24-7
  • 7
  • 3