I try to use the following code to empty a database (delete all tables) :
SELECT concat('DROP TABLE IF EXISTS ','`',table_schema,'`','.','`',table_name,'`',';') FROM information_schema.tables WHERE table_schema = 'DB';
I am getting an output of the commands, but nothing happens to the database. If I take an individual command from the output, and run it in the console, it works.
What am I doing wrong?
As you know, SELECT only returns the result of a query. It doesn't know you actually intend to execute the result of that query. (In most cases, that would make no sense.) You can use prepared statements to do what you want (untested):
SET #s:='';
SELECT #s:=concat(#s, 'DROP TABLE IF EXISTS ','`',table_schema,'`','.','`',table_name,'`',';') FROM information_schema.tables WHERE table_schema = 'DB';
PREPARE stm FROM #s;
EXECUTE stm;
DEALLOCATE PREPARE stm;
Why you're using SELECT statement, Simply try this query:
DROP TABLE IF EXISTS table_name;
Related
I am trying to store the output of the following query into a view or a temporary table. I know that view requires the SELECT statement but I was wondering if it could work as well with the EXECUTE command.
This is my query:
SET #por= NULL;
SELECT
CONCAT(GROUP_CONCAT(
DISTINCT
CONCAT('SELECT * FROM ', table_name)
SEPARATOR '\r\nUNION\r\n'
), '\r\nUNION\r\n', 'select * from table1')
INTO
#union_por_tables
FROM
information_schema.tables
WHERE
table_schema = 'schema' AND table_name LIKE '%por%';
PREPARE stmt1 FROM #union_por_tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1
This query return me 250000 rows and I want to store them. Can someone help me?
What you described is referred to as materialized view
From what I know at the moment, MySQL doesn't support materialized views. You can simulate it by inserting data in an actual table, thus maintaining the cache manually.
MariaDB implements materialized views via something they refer to as flexviews. The docs are here: https://mariadb.com/kb/en/library/flexviews/
You might explore the option of trying out MariaDB and its flexviews feature for your particular use case.
I want to be able to do something like this:
SET #foo_width = 10;
CREATE TABLE test_table (
foo varchar(#foo_width)
);
The exact problem is that I will need the same varchar-width for different columns across different tables. So, thought it'd be better if it could be stored in a variable.
Is there any alternative?
You can't do it directly, and MySQL doesn't support user-defined types.
At best, you can use PREPARED STATEMENT like this or you generate your query in your application.
SET #foo_width = 10;
SELECT CONCAT("CREATE TABLE test_table (
foo varchar(",#foo_width,")
);") INTO #myquery;
select #myquery; -- only for test
PREPARE stmt FROM #myquery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
I have an old script that creates each day a table and store data in it.
The table names are like this today-date-some-other-string, i.e : 02-02-2018-other-string.
The question is, how could I describe the structure of that table despite I only have today's date? I mean is there a way to do something like this :
DESC WHERE Table like "02-02-2018%"
Thank you.
In mysql you could use prepared statements for example
set #sql = concat('describe ' , (select table_name
from information_schema.tables
where table_name like 'users' and table_schema = 'sandbox')
,';');
prepare sqlstmt from #sql;
execute sqlstmt;
deallocate prepare sqlstmt;
I've found another thread on this question, but I wasn't able to use its solutions, so I thought I'd ask with more clarity and detail.
I have a large MySQL database representing a vBulletin forum. For several years, this forum has had an error generated on each view, each time creating a new table named aagregate_temp_1251634200, aagregate_temp_1251734400, etc etc. There are about 20,000 of these tables in the database, and I wish to delete them all.
I want to issue a command that says the equivalent of DROP TABLE WHERE TABLE_NAME LIKE 'aggregate_temp%';.
Unfortunately this command doesn't work, and the Google results for this problem are full of elaborate stored procedures beyond my understanding and all seemingly tailored to the more complex problems of different posters.
Is it possible to write a simple statement that drops multiple tables based on a name like match?
There's no single statement to do that.
The simplest approach is to generate a set of statements, and execute them individually.
We can write a simple query that will generate the statements for us:
SELECT CONCAT('DROP TABLE `',t.table_schema,'`.`',t.table_name,'`;') AS stmt
FROM information_schema.tables t
WHERE t.table_schema = 'mydatabase'
AND t.table_name LIKE 'aggregate\_temp%' ESCAPE '\\'
ORDER BY t.table_name
The SELECT statement returns a rowset, but each row conveniently contains the exact SQL statement we need to execute to drop a table. (Note that information_schema is a builtin database that contains metadata. We'd need to replace mydatabase with the name of the database we want to drop tables from.
We can save the resultset from this query as a plain text file, remove any heading line, and voila, we've got a script we can execute in our SQL client.
There's no need for an elaborate stored procedure.
A little googling found this:
SELECT 'DROP TABLE "' + TABLE_NAME + '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'prefix%'
This should generate a script.
Source: Drop all tables whose names begin with a certain string
From memory you have to use prepared statements, for example: plenty of samples on stack exchange
I would recommend this example:
SQL: deleting tables with prefix
The SQL from above, this one includes the specific databasename - it builds it for you
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' )
AS statement FROM information_schema.tables
WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';
Here is a different way to do it:
MySQL bulk drop table where table like?
This will delete all tables with prefix "mg_"
No need to copy and paste rowsets and in phpadmin copying and pasting is problematic as it will cut off long table names and replace them with '...' ruining set of sql commands.
Also note that '_' is a special character so thats why 'mg_' should be encoded as 'mg\_'
(and FOREIGN_KEY_CHECKS needs to be disabled in order to avoid error messages)
SET FOREIGN_KEY_CHECKS = 0;
SET GROUP_CONCAT_MAX_LEN=32768;
SET #tables = NULL;
SELECT GROUP_CONCAT('`', table_name, '`') INTO #tables
FROM information_schema.tables
WHERE table_schema = (SELECT DATABASE()) and table_name like 'mg\_%';
SELECT IFNULL(#tables,'dummy') INTO #tables;
SET #tables = CONCAT('DROP TABLE IF EXISTS ', #tables);
PREPARE stmt FROM #tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE (
SELECT table_name
FROM information_schema.`TABLES`
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%');
I know this doesn't work! What is the equivalent for something like this in SQL? I can whip out a simple Python script to do this but was just wondering if we can do something with SQL directly. I am using MySQL. Thank you!
You can use prepared statements -
SET #tables = NULL;
SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name,'`') INTO #tables FROM information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%';
SET #tables = CONCAT('DROP TABLE ', #tables);
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
It will generate and execute a statement like this -
DROP TABLE myDatabase.del1, myDatabase.del2, myDatabase.del3;
A minor improvement to #Devart's answer:
SET #tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.`', table_name, '`') INTO #tables FROM
(select * from
information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE 'del%'
LIMIT 10) TT;
SET #tables = CONCAT('DROP TABLE ', #tables);
select #tables;
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
This script should be executed repeatedly until the console's output is NULL
The changes are:
backtick (`) wrapping the table name (if it contains non standard characters)
added a LIMIT to avoid the truncation issue I commented about
added a "print" (select #tables;) to have some kind of control when to stop executing the script
If you just need to quickly drop a bunch of tables (not in pure SQL, so not directly answering this question) a one line shell command can do it:
echo "show tables like 'fsm%'" | mysql | tail +2 | while read t; do echo "drop table \`$t\`;"; done | mysql
I found it useful to add an IFNULL to Devart's solutions to avoid generating an error if there are no tables matching the query.
SET #tables = IFNULL(CONCAT('DROP TABLE ', #tables),'SELECT NULL;');
In addition to #Devart's answer:
If you have many tables, you may need to set group_concat_max_len:
SET group_concat_max_len = 4096;
You can do this quickly and easily if you have phpMyAdmin available and the requirement is to drop tables with a specific prefix. Go to the database you want, and show the list of all the tables. Since tables are shown in alphabetic order, the tables with the prefix for deletion will all appear together. Go to the first one, and click the tick box on the left hand side. Then scroll down to the last table with the prefix, hold down shift, and click the tick box. That results in all the tables with the prefix being ticked. Go to the bottom of the list, and select the action drop for all selected tables. Go through with the deletion, checking that the SQL generated looks right!