MySQL:プレフィックスで始まるDROP TABLE


8

例:プレフィックス「dp_」で始まる30を超えるテーブルと、「ex_」で始まる約12のテーブルがあります。

質問:「dp_」で始まるすべてのテーブルを1つのクエリで削除するにはどうすればよいですか?


ストアドプロシージャを使用せずにテーブルの削除を実行するように回答を更新しました。試してみる !!!
RolandoMySQLDBA

回答:


11

データベースとプレフィックス文字列をパラメーターとして受け入れるストアドプロシージャを次に示します。

DELIMITER $$

DROP PROCEDURE DropTablesWithPrefix $$
CREATE PROCEDURE DropTablesWithPrefix(db VARCHAR(64),prfx VARCHAR(20))
StoredProcedure:BEGIN
    DECLARE ndx,maxidx INT;
    DECLARE giventable,SQLSTMT VARCHAR(500);

    CREATE TABLE TableZapList
    (
        droptablesql VARCHAR(512),
        idx INT NOT NULL AUTO_INCREMENT PRIMARY KEY
    ) ENGINE=MyISAM;

    INSERT INTO TableZapList (droptablesql)
    SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name)
    FROM information_schema.tables
    WHERE table_schema = db AND SUBSTR(table_name,LENGTH(prfx)) = prfx;
    SELECT COUNT(1) INTO maxid FROM TableZapList;

    IF maxid = 0 THEN
        LEAVE StoredProcedure;
    END IF;<BR>

    SET ndx = 0;
    WHILE ndx < maxid DO
        SET ndx = ndx + 1;
        SELECT droptablesql INTO SQLSTMT FROM TableZapList WHERE idx = ndx;
        SET @sql = SQLSTMT;
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    END WHILE;<BR>

    SELECT droptablesql FROM TableZapList;
    DROP TABLE TableZapList;
END;

DELIMITER ;

UPDATE 2011-07-12 14:55 EDT

私はより簡潔で単純な方法を考えました。ストアドプロシージャを使用する代わりに、GROUP_CONCAT関数を使用して、すべてのテーブルを収集してザップします。次に、単一のクエリに構成します。

以下は、現在のデータベースのwp_polで始まるすべてのテーブルを削除するクエリです。

SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(table_schema,'.',table_name)),';')
FROM information_schema.tables
WHERE table_schema=database()
AND table_name like 'wp_pol%';

次に行うことは、その結果を保存することです

SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(table_schema,'.',table_name)),';')
INTO @dropcmd
FROM information_schema.tables
WHERE table_schema=database()
AND table_name like 'wp_pol%';

最後に、次の3つのコマンドを使用して動的SQLを実行します。

PREPARE s1 FROM @dropcmd;
EXECUTE s1;
DEALLOCATE PREPARE s1;

これは、WindowsでMySQL 5.5.12を使用して動作するデモです。

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.5.12 MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

MySQL (Current test) :: use garbage
Database changed
MySQL (Current garbage) :: show tables;
+------------------------------+
| Tables_in_garbage            |
+------------------------------+
| datas                        |
| rolando                      |
| wp_commentmeta               |
| wp_comments                  |
| wp_contact_form_7            |
| wp_links                     |
| wp_most_read_hits            |
| wp_options                   |
| wp_pollsa                    |
| wp_pollsip                   |
| wp_pollsq                    |
| wp_postmeta                  |
| wp_posts                     |
| wp_posts_idtracker           |
| wp_tantan_wordpress_s3_cache |
| wp_term_relationships        |
| wp_term_taxonomy             |
| wp_terms                     |
| wp_usermeta                  |
| wp_users                     |
| wp_w3tc_cdn_queue            |
+------------------------------+
21 rows in set (0.00 sec)

MySQL (Current garbage) :: SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(table_schema,'.',table_name)),';') INTO @dropcmd FROM information_schema.tables WHERE table_schema=database() AND table_name like 'wp_pol%';
Query OK, 1 row affected (0.00 sec)

MySQL (Current garbage) :: SELECT @dropcmd;
+--------------------------------------------------------------------+
| @dropcmd                                                           |
+--------------------------------------------------------------------+
| DROP TABLE garbage.wp_pollsa,garbage.wp_pollsip,garbage.wp_pollsq; |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)

MySQL (Current garbage) :: PREPARE s1 FROM @dropcmd; EXECUTE s1; DEALLOCATE PREPARE s1;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

MySQL (Current garbage) :: show tables;
+------------------------------+
| Tables_in_garbage            |
+------------------------------+
| datas                        |
| rolando                      |
| wp_commentmeta               |
| wp_comments                  |
| wp_contact_form_7            |
| wp_links                     |
| wp_most_read_hits            |
| wp_options                   |
| wp_postmeta                  |
| wp_posts                     |
| wp_posts_idtracker           |
| wp_tantan_wordpress_s3_cache |
| wp_term_relationships        |
| wp_term_taxonomy             |
| wp_terms                     |
| wp_usermeta                  |
| wp_users                     |
| wp_w3tc_cdn_queue            |
+------------------------------+
18 rows in set (0.00 sec)

MySQL (Current garbage) ::

試してみる !!!


Rolandosスクリプトは機能しますが、テーブルがたくさんある場合やテーブル名が非常に長い場合は、パラメーターgroup_concat_max_lenを増やす必要があるかもしれません。SETSESSION group_concat_max_len = 1000000;
JohnP

group + concat_max_lenを変更する代わりに、制限付きのサブクエリを使用して、段階的にドロップを実行しました
pedromanoel

SUBSTR条件は次のINSERTとおりSUBSTR(table_name, 1, LENGTH(prfx)) = prfxです。正常に機能します。
laurent

8

まず、Unixプロンプトでこれを行うスクリプトを生成します。

$  echo "select concat('drop table ', table_name, ';') from information_schema.tables where table_name like 'prefix_%';" |mysql --user=root --password=blah --batch >drop.sql

プレフィックスを独自のものに置き換えます。この--batchオプションは、MySQLがデフォルトで行う高度なフォーマットを抑制し、実行可能なSQLスクリプトを生成できるようにします。

スクリプトを確認し、問題がなければdrop.sqlmysql>プロンプトで実行します。


私はすでにこれを行うためにphpヘルパースクリプトを実行しましたが、単一のクエリを使用して実行できるかどうか疑問に思っていました。
poelinca

1
単純な答え:いいえ。複雑な答え:はい、それをストアドプロシージャでラップする場合。したがって、1つのコマンドで実行できますが、スクリプトを呼び出すのと同じです。
ガイウス

4

これらのテーブル名についてシステムテーブルをクエリし、文字列を作成して動的に実行する必要があります。SQL Serverでは、次のようにします。

declare @x varchar(max), @enter char(2);
select @x = '', @enter = char(13)+char(10);

Select @x = @x + 'drop table ' + table_name + ';' + @enter    
from information_schema.tables    
where table_name like '%accounting%'

print @x
execute (@x);

次に、MySQLで対応するシステムテーブルを見つける必要があります。


私はあなたの答えをとても注意深く読みました。これは私の答えと同義です。SQL Serverの方言では、原則として、あなたの答えは最初の正しい答えです。+1 !!!
RolandoMySQLDBA 2011

3

あなたの質問に答えるために、いいえ。MySQLでは単一のコマンド/クエリを使用しません。コマンドをチェーンする必要があります。

ただし、目標を達成したい場合は、次の1つの方法があります。

次のようなbashスクリプトから:

#/bin/bash
TABLES=`mysql -s -e "SELECT CONCAT(TABLE_SCHEMA,'.',TABLE_NAME) AS T FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'dp_%'" -u user -p`

for i in $TABLES; 
do 
 echo "DROP TABLE $i;" >> drops.sql ; 
done

cat drops.sql

次に、drops.sqlファイルを確認します。すべて問題なければ、バックアップを作成してください...

mysql -u username -p -v --show-warnings < drops.sql

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.