Drop multiple tables in one shot in MySQL - mysql

How to drop multiple tables from one single database at one command.
something like,
> use test;
> drop table a,b,c;
where a,b,c are the tables from database test.

We can use the following syntax to drop multiple tables:
DROP TABLE IF EXISTS B,C,A;
This can be placed in the beginning of the script instead of individually dropping each table.

SET foreign_key_checks = 0;
DROP TABLE IF EXISTS a,b,c;
SET foreign_key_checks = 1;
Then you do not have to worry about dropping them in the correct order, nor whether they actually exist.
N.B. this is for MySQL only (as in the question). Other databases likely have different methods for doing this.

A lazy way of doing this if there are alot of tables to be deleted.
Get table using the below
For sql server - SELECT CONCAT(name,',') Table_Name FROM SYS.tables;
For oralce - SELECT CONCAT(TABLE_NAME,',') FROM SYS.ALL_TABLES;
Copy and paste the table names from the result set and paste it after the DROP command.

declare #sql1 nvarchar(max)
SELECT #sql1 =
STUFF(
(
select ' drop table dbo.[' + name + ']'
FROM sys.sysobjects AS sobjects
WHERE (xtype = 'U') AND (name LIKE 'GROUP_BASE_NEW_WORK_%')
for xml path('')
),
1, 1, '')
execute sp_executesql #sql1

Related

mysql stored procedure - check if query returns no result

I am creating a stored procedure, where I'm backing up certain values from my main database into another.
I have a loop that runs over the all tables and for certain tables I have different statements to create the backup tables, but they all look similar to this:
SET #backupQuery= NULL;
IF (tableName IN ('some_table', 'another_table')) THEN
SET #backupQuery= CONCAT(
'CREATE TABLE backup.', tableName, ' AS',
' SELECT * FROM mydb.', tableName
' WHERE row = "criteria");
ELSEIF (tableName IN ('table_with_other criteria')) THEN
SET #backupQuery= CONCAT(
...
IF (#backupQueryIS NOT NULL) THEN
PREPARE stmt from #backupQuery;
...
If the Select statement returns no rows, it still creates an empty table, this is something i don't want to have.
What will be the best way to avoid the empty tables?
My idea was to split into two parts: the SELECT part and the 'CREATE TABLE backup.' ,tableName, ' AS' part. Check if the SELECT statement returned any rows.
But I'm not sure how I can accomplish this.
Another approach would be to delete all empty tables in the end, but I really don't like this as the procedure is doing useless things.

How to delete all tables that have 1-2 rows

Im having a database which is over 60k tables and i want to delete all the tables that have 1 or 2 rows.
You can use the below code in SQL Server 2012. It will delete all the tables which is having row_count less than 3.
USE [YourDB]
GO
DECLARE #Max int, #Count int,#Table_Name Varchar(20)
SET #Max =0
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
table_name sysname ,
row_count INT,
reserved_size VARCHAR(50),
data_size VARCHAR(50),
index_size VARCHAR(50),
unused_size VARCHAR(50)
)
IF OBJECT_ID('tempdb..#temp1') IS NOT NULL
DROP TABLE #temp1
CREATE TABLE #temp1
(
ID int IDENTITY(1,1),
table_name sysname ,
row_count INT
)
SET NOCOUNT ON
INSERT #temp
EXEC sp_msforeachtable 'sp_spaceused ''?'''
INSERT INTO #temp1
SELECT a.table_name,
a.row_count
FROM #temp a
INNER JOIN information_schema.columns b
ON a.table_name collate database_default
= b.table_name collate database_default
GROUP BY a.table_name, a.row_count
HAVING a.row_count <3
SET #Count =(SELECT COUNT(*) FROM #temp1)
WHILE #Count > #Max
BEGIN
SET #Max = #Max +1
SET #Table_Name = (SELECT table_name FROM #temp1 WHERE ID = #Max)
EXEC('DROP TABLE ' +#Table_Name)
END
Use a MySQL-GUI, order by number of rows and drop all tables with 1-2 rows. it is as easy as deleting files in a windows folder. this
would take ~10 seconds + sort and drop time
or
Select table names of tables with 1-2 rows from information_schemas, load into an excel file and build your drop statements. takes around 2-5 minutes + drop time
or
Build a stored procedure that uses a Cursor to parse all the relevant table names into variables of your drop statement (like Hansa mentioned). this makes sense if you want to repeat your process from time to time. takes around 1-12 hours for beginners (depending on knowledge level) + drop time
Since logging in on SO probably took more time than solution 1 would,
i would recommend that solution.
In case you want to spend more time , the following query will show all table names for tables with 1-2 rows:
SELECT table_schema, table_name From information_schema.tables
WHERE table_schema='your_schema' # use your table_schema here
AND table_rows BETWEEN 1 and 2 ;
I would do it within some application side logic, using a programming language of your choice (which offers a mysql API).
Get all table names, described here, grouping them by table names
e.g. this could look something like:
SELECT COUNT(table_rows), table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '{your_db}'
GROUP BY table_name;
(this is not tested, but to give you a basic idea...)
Execute a delete statement for the tables with rowcount 2 or lower. Should be an easy task as soon as you got the results in your programming language (btw SQL statement to delete them is "DROP TABLE")
Note: I think it should be also possible using a SQL cursor, but as I said I would prefer the above solution.
You can try this.
First take all the table names from the database.
After getting all the table names put them in a array and execute a foreach loop that checks the num of rows for each table, something like this
$tables = array();
foreach ($tables as $table_name){
$query = "select * from '$table_name'";
$result = mysqli_query($dbCon, $query);
$num_rows = mysql_num_rows($result);
if($num_rows < 3){
$delete = "drop table $table_name";
$res_del = mysqli_query($dbCon, $delete);
echo $table_name." Deleted";
}
}
You probably cant do this with 1 SQL Statement unless you are using stored procedures (see below).
You will need to select all tables in MySQL with a programming language (e.g. Java with JDBC) using the following statement:
select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_ROWS <= 2 AND TABLE_ROWS >= 1
Then you can use the results in the programming languge to issue drop Statements for each result record in a loop:
drop table <tablename>
For doing this with a stored procedure (i.e. without a programming language)
see the third comment on this page: MySQL Reference Drop Table.
Of course you will need to adapt this to your needs because this example does not select tables by their row numbers but by their names.

how can I get the sql statements used to create a specific table?

Suppose if I have access to a mysql database, and there exists a table named "users", how could I get the sql statements used to create that specific table? Is there any way to do it by a simple command in mysql shell?
SHOW CREATE TABLE tablename (mysql only)
in MS SQL
It is pretty long but it is what I do when needed
declare #clms nvarchar(max)
declare #tbl nvarchar(max)='a1'
select #clms= coalesce(#clms,'(')+column_name+ ' '+data_type+
case when data_type in ('nvarchar','varchar','char') then '(255)' else '' end + ', '
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=#tbl
select 'create table ' + #tbl +left(#clms,len(#clms)-1)+')'

How to create a Trigger for creating the columns in a table on the insertion of data in another table

I am having a table MstAttributes another as TrnIndexAttributes. I want to create those many columns in TrnIndexAttributes table as many rows are there in MstAttributes. Means after insertion of a value in MstAttributesone column should be created in TrnIndexAttribute table like ID1,ID2,ID3....
If you really feel like doing that (despite the rightful warning of Philip Kelley), you'll have to use dynamic query.
DECLARE #Query NVARCJAR(MAX) = N'ALTER TABLE TableOfInfiniteDoom ADD COLUMN' + [your logic for a name] + [your ligic for a type]
EXEC sp_executesql #Query
In your trugger (don't fortget the loop if you handle multyrows DML).

Using dynamic sql to populate a temp table

I know this isn't ideal, but I would like to know if it is possible to populate a temp table based on dynamic sql?
A very similar example to what I want to achieve is shown in this answer as either
SELECT into #T1 execute ('execute ' + #SQLString )
or
INSERT into #T1 execute ('execute ' + #SQLString )
I couldn't get either to work. It seems from the edit that the first option was wrong, so for the second option I've tried something like;
DECLARE #SQLString VARCHAR (2000) = 'SELECT * FROM INFORMATION_SCHEMA.COLUMNS'
INSERT into #MyTempTable execute (#SQLString )
Any ideas are much appreciated.
Edit:
In an attempt to clarify what I am trying to do without being too localised, I explain as briefly as I can below.
I have data in a staging area of my database that contains tables with dynamic names and a dynamic number of columns. However, a few of the column names are the same for each table. Rather than construct everything in dynamic sql, I would like to be able to simply extract the known columns into a temp table (or table variable, CTE, derived table or whatever) and act on that.
So given a table as so;
CREATE TABLE SomeParticularNameThatCantBeKnownToAStoredProc (
[1] AS VARCHAR(100),
[2] AS VARCHAR(100),
... -- Could be any number of these columns
[Id] AS INT,
[KnownCol] AS VARCHAR(100),
[KnownCol2] AS VARCHAR(100),
....
[DboId] AS INT
)
I'd like to be able to perform the necessary operations to allow my to process this data without having to do it all in dynamic sql. I was hoping to be able to do something like;
DECLARE #TableName AS VARCHAR(1000) = 'SomeParticularNameThatCantBeKnownToAStoredProc'
SELECT [Id], [KnownCol], [KnownCol2], [DboId]
INTO #KnownName
FROM #TableName -- I know this isn't possible, but this is what I'd like to do
This would then allow me to perform SQL statements against a consistent #KnownName. Some of the other operations I need to do are quite lengthy such as using the data to relate to other existing tables, copying data from the staging table(s) to their dbo schema equivalents and matching the DboId against the staging table Id using MERGE with OUTPUT INTO as described here, and so on and so forth.
If you can think of any other way I can limit the amount of dynamic SQL I need to write given the fact that the table name is dynamic then please let me know.
Assuming #MyTempTable already exists:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT * FROM INFORMATION_SCHEMA.COLUMNS;';
INSERT #MyTempTable EXEC sp_executesql #SQLString;
Otherwise please clarify what you are trying to do. If the table isn't already created, you can do everything inside of dynamic SQL, e.g.:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT * INTO #MyTempTable FROM INFORMATION_SCHEMA.COLUMNS;
SELECT * FROM #MyTempTable;';
EXEC sp_executesql #sql;