Reputation: 133
To drop a bunch of tables in our db, the following works (thank you @Devart from here for help getting this far)
SET @tables = NULL;
SET @db='tech';
SET @days = 365;
SELECT GROUP_CONCAT(@db, '.`',table_name, '`') INTO @tables FROM
(select t.table_name, ifnull(t.UPDATE_TIME, t.CREATE_TIME) update_time from
information_schema.tables t) TT;
SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
SELECT @tables;
PREPARE stmt1 FROM @tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
The problem is that I want to add a where clause with variables in the nested select statement that looks like this:
CONCAT(WHERE t.table_schema=\'', @db, '\' AND IFNULL(t.UPDATE_TIME, t.CREATE_TIME) < CURDATE()-INTERVAL ', @days, 'DAY AND (TABLE_NAME NOT LIKE \'%_delete\' OR TABLE_NAME RLIKE \'[0-9].*\'));
The only way I know of to intermittently have variables in a query is to use CONCAT and then PREPARE and EXECUTE that query. The problem is I can't save the result that has multiple columns in a variable like this
SET @schema_info = CONCAT('select t.table_name, ifnull(t.UPDATE_TIME, t.CREATE_TIME) update_time
from information_schema.tables t
WHERE t.table_schema=\'', @db, '\' AND IFNULL(t.UPDATE_TIME, t.CREATE_TIME) < CURDATE()-INTERVAL ', @days, 'DAY AND (TABLE_NAME NOT LIKE \'%_delete\' OR TABLE_NAME RLIKE \'[0-9].*\')');
PREPARE stmt FROM @schema_info;
SET @result = EXECUTE stmt;
SELECT GROUP_CONCAT(@db, '.`',table_name, '`') INTO @tables FROM
(@result);
and I can't nest the execute statement like this
SET @schema_info = CONCAT('select t.table_name, ifnull(t.UPDATE_TIME, t.CREATE_TIME) update_time
from information_schema.tables t
WHERE t.table_schema=\'', @db, '\' AND IFNULL(t.UPDATE_TIME, t.CREATE_TIME) < CURDATE()-INTERVAL ', @days, 'DAY AND (TABLE_NAME NOT LIKE \'%_delete\' OR TABLE_NAME RLIKE \'[0-9].*\')');
PREPARE stmt FROM @schema_info;
SELECT GROUP_CONCAT(@db, '.`',table_name, '`') INTO @tables FROM
(EXECUTE stmt);
Is there any other way to do this without using a separate stored procedure or function?
Upvotes: 1
Views: 408
Reputation: 562671
You don't need to do this as a prepared statement. You can use variables in your SQL expression without concat-prepare-execute. They act like a single scalar value, so there's no risk of SQL injection.
SELECT GROUP_CONCAT(@db, '.`',table_name, '`') INTO @tables
FROM (
SELECT t.table_name, IFNULL(t.UPDATE_TIME, t.CREATE_TIME) update_time
FROM information_schema.tables t
WHERE t.table_schema = @db
AND IFNULL(t.UPDATE_TIME, t.CREATE_TIME) < CURDATE()-INTERVAL @days DAY
AND (TABLE_NAME NOT LIKE '%_delete' OR TABLE_NAME RLIKE '[0-9].*')
) TT;
Upvotes: 1