web-dev-qa-db-ja.com

MySQLは外部キーを無視してすべてのテーブルを削除します

そこにあるかもしれないどんな外部キー制約も無視して、MySQLデータベースからすべてのテーブルを削除するための素晴らしい簡単な方法はありますか?

334
bcmcfc

生成された一連のdropステートメントが有用であることがわかり、これらの調整をお勧めします。

  1. このようにして、生成されるドロップをデータベースに制限します。
SELECT concat('DROP TABLE IF EXISTS `', table_name, '`;')
FROM information_schema.tables
WHERE table_schema = 'MyDatabaseName';

注:これはDROPステートメントを実行するのではなく、単にそれらのリストを表示するだけです。それらを実行するには、出力を切り取り、SQLエンジンに貼り付ける必要があります。

  1. 注: http://dev.mysql.com/doc/refman/5.5/en/drop-table.html によると、カスケードでドロップするのは無意味です。誤解を招く

"RESTRICTとCASCADEは移植を容易にすることを許可されています。MySQL5.5では、それらは何もしません。"

したがって、必要に応じてdropステートメントを機能させるには、次のようにします。

SET FOREIGN_KEY_CHECKS = 0

これは参照整合性チェックを無効にします - ですからあなたが必要なドロップを実行し終わったら、キーチェックをリセットしたいでしょう。

SET FOREIGN_KEY_CHECKS = 1
  1. 最終的な実行は次のようになります。
SET FOREIGN_KEY_CHECKS = 0;
-- Your semicolon separated list of DROP statements here
SET FOREIGN_KEY_CHECKS = 1;

注意:SELECTの出力をより使いやすくするために、mysql -Bオプションが役立ちます。

381
Dion Truter

http://www.devdaily.com/blog/post/mysql/drop-mysql-tables-in-any-order-foreign-keysから

SET FOREIGN_KEY_CHECKS = 0;
drop table if exists customers;
drop table if exists orders;
drop table if exists order_details;
SET FOREIGN_KEY_CHECKS = 1;

(これは、任意の順序でテーブルを削除できるようにするために外部キーチェックを無効にする方法に答えます。既存のすべてのテーブルに対してテーブル削除ステートメントを自動的に生成して単一のスクリプトで実行する方法には答えません。 ジーンの答え します。)

124
chiccodoro

SurlyDreのストアドプロシージャは、外部キーが無視されるように修正されています。

DROP PROCEDURE IF EXISTS `drop_all_tables`;

DELIMITER $$
CREATE PROCEDURE `drop_all_tables`()
BEGIN
    DECLARE _done INT DEFAULT FALSE;
    DECLARE _tableName VARCHAR(255);
    DECLARE _cursor CURSOR FOR
        SELECT table_name 
        FROM information_schema.TABLES
        WHERE table_schema = SCHEMA();
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;

    SET FOREIGN_KEY_CHECKS = 0;

    OPEN _cursor;

    REPEAT FETCH _cursor INTO _tableName;

    IF NOT _done THEN
        SET @stmt_sql = CONCAT('DROP TABLE ', _tableName);
        PREPARE stmt1 FROM @stmt_sql;
        EXECUTE stmt1;
        DEALLOCATE PREPARE stmt1;
    END IF;

    UNTIL _done END REPEAT;

    CLOSE _cursor;
    SET FOREIGN_KEY_CHECKS = 1;
END$$

DELIMITER ;

call drop_all_tables(); 

DROP PROCEDURE IF EXISTS `drop_all_tables`;

上記のすべてのアプローチには、この1つのAFAICTよりもはるかに多くの作業が含まれています...

( mysqldump --add-drop-table --no-data -u root -p database | grep 'DROP TABLE' ) > ./drop_all_tables.sql
mysql -u root -p database < ./drop_all_tables.sql
32
SkyLeach

この答えから、

実行する:

  use `dbName`; --your db name here
  SET FOREIGN_KEY_CHECKS = 0; 
  SET @tables = NULL;
  SET GROUP_CONCAT_MAX_LEN=32768;

  SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name, '`') INTO @tables
  FROM   information_schema.tables 
  WHERE  table_schema = (SELECT DATABASE());
  SELECT IFNULL(@tables, '') INTO @tables;

  SET        @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
  PREPARE    stmt FROM @tables;
  EXECUTE    stmt;
  DEALLOCATE PREPARE stmt;
  SET        FOREIGN_KEY_CHECKS = 1;

現在使用中のデータベースからテーブルを削除します。現在のデータベースはuseを使って設定できます。


それ以外の場合は、最初にクエリを取得し、次にクエリを実行するために2回実行する必要がある点を除いて、Dionの一般的な回答はより単純です。 dbとテーブル名の中の特殊文字をエスケープするためにいくつかの愚かなバックティックを提供しました。

  SELECT CONCAT('DROP TABLE IF EXISTS `', table_schema, '`.`', table_name, '`;')
  FROM   information_schema.tables
  WHERE  table_schema = 'dbName'; --your db name here
19
nawfal

これがカーソルベースの解決策です。 Kindaは長いですが、単一のSQLバッチとして機能します。

DROP PROCEDURE IF EXISTS `drop_all_tables`;

DELIMITER $$
CREATE PROCEDURE `drop_all_tables`()
BEGIN
    DECLARE _done INT DEFAULT FALSE;
    DECLARE _tableName VARCHAR(255);
    DECLARE _cursor CURSOR FOR
        SELECT table_name 
        FROM information_schema.TABLES
        WHERE table_schema = SCHEMA();
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;

    OPEN _cursor;

    REPEAT FETCH _cursor INTO _tableName;

    IF NOT _done THEN
        SET @stmt_sql = CONCAT('DROP TABLE ', _tableName);
        PREPARE stmt1 FROM @stmt_sql;
        EXECUTE stmt1;
        DEALLOCATE PREPARE stmt1;
    END IF;

    UNTIL _done END REPEAT;

    CLOSE _cursor;

END$$

DELIMITER ;

call drop_all_tables(); 

DROP PROCEDURE IF EXISTS `drop_all_tables`;
16
SurlyDre

できるよ:

select concat('drop table if exists ', table_name, ' cascade;')
  from information_schema.tables;

その後、生成されたクエリを実行します。それらは現在のデータベース上のすべての単一のテーブルを削除します。

ここでdrop tableコマンドのヘルプです。

11

私はDion Truterの答えにこの修正を思い付きました。

SET GROUP_CONCAT_MAX_LEN = 10000000;
SELECT CONCAT('SET FOREIGN_KEY_CHECKS=0;\n', 
              GROUP_CONCAT(CONCAT('DROP TABLE IF EXISTS `', table_name, '`')
                           SEPARATOR ';\n'),
              ';\nSET FOREIGN_KEY_CHECKS=1;')
FROM information_schema.tables
WHERE table_schema = 'SchemaName';

これは1つのフィールドにすべてのものを返すので、一度コピーしてすべてのテーブルを削除することができます(WorkbenchのCopy Field Content (unquoted)を使用します)。たくさんのテーブルがある場合、GROUP_CONCAT()にいくつかの制限があります。もしそうなら、max len変数(そして必要ならばmax_allowed_packet)を増やしてください。

9
Ryan P

これは、bashスクリプトを使ってこれを自動化する方法です。

Host=$1
dbName=$2
user=$3
password=$4

if [ -z "$1" ]
then
    Host="localhost"
fi

# drop all the tables in the database
for i in `mysql -u$user -p$password $dbName -e "show tables" | grep -v Tables_in` ; do  echo $i && mysql -u$user -p$password $dbName -e "SET FOREIGN_KEY_CHECKS = 0; drop table $i ; SET FOREIGN_KEY_CHECKS = 1" ; done
5
kfox

Linux(あるいは、pipe、echo、およびgrepをサポートする他のシステム)の場合は、1行で実行できます。

echo "SET FOREIGN_KEY_CHECKS = 0;" > temp.txt; \
mysqldump -u[USER] -p[PASSWORD] --add-drop-table --no-data [DATABASE] | grep ^DROP >> temp.txt; \
echo "SET FOREIGN_KEY_CHECKS = 1;" >> temp.txt; \
mysql -u[USER] -p[PASSWORD] [DATABASE] < temp.txt;

私はこれが古い質問であることを知っています、しかし私はこの方法が速くて簡単であると思います。

5
moretti.fabio

特定のデータベースからすべてのテーブルを削除するための1つのライナーです。

echo "DATABASE_NAME"| xargs -I{} sh -c "mysql -Nse 'show tables' {}| xargs -I[] mysql -e 'SET FOREIGN_KEY_CHECKS=0; drop table []' {}"

これを実行すると、データベースDATABASE_NAMEからすべてのテーブルが削除されます。

そしてこれに関する素晴らしいことは、データベース名が明示的に一度だけ書かれることです。

5
mgershen

トピックをグーグルすると、常にこの[SO]質問が表示されるので、両方のテーブルとビューを削除するmysqlコードを使用しています。

DROP PROCEDURE IF EXISTS `drop_all_tables`;

DELIMITER $$
CREATE PROCEDURE `drop_all_tables`()
BEGIN
    DECLARE _done INT DEFAULT FALSE;
    DECLARE _tableName VARCHAR(255);
    DECLARE _cursor CURSOR FOR
        SELECT table_name
        FROM information_schema.TABLES
        WHERE table_schema = SCHEMA();
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;

    SET FOREIGN_KEY_CHECKS = 0;

    OPEN _cursor;

    REPEAT FETCH _cursor INTO _tableName;

    IF NOT _done THEN
        SET @stmt_sql1 = CONCAT('DROP TABLE IF EXISTS ', _tableName);
        SET @stmt_sql2 = CONCAT('DROP VIEW IF EXISTS ', _tableName);

        PREPARE stmt1 FROM @stmt_sql1;
        PREPARE stmt2 FROM @stmt_sql2;

        EXECUTE stmt1;
        EXECUTE stmt2;

        DEALLOCATE PREPARE stmt1;
        DEALLOCATE PREPARE stmt2;
    END IF;

    UNTIL _done END REPEAT;

    CLOSE _cursor;
    SET FOREIGN_KEY_CHECKS = 1;
END$$

DELIMITER ;

call drop_all_tables();

DROP PROCEDURE IF EXISTS `drop_all_tables`;
3
Sergey Alaev

Bash/zshのようなLinuxシェルでは、

DATABASE_TO_EMPTY="your_db_name";
{ echo "SET FOREIGN_KEY_CHECKS = 0;" ; \
  mysql "$DATABASE_TO_EMPTY" --skip-column-names -e \
  "SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') \
   FROM information_schema.tables WHERE table_schema = '$DATABASE_TO_EMPTY';";\
  } | mysql "$DATABASE_TO_EMPTY"

これによりコマンドが生成され、すぐにそれらをテーブルを削除する2番目のクライアントインスタンスにパイプします。

巧妙な部分はもちろん他の答えからここにコピーされます - 私は実際にdoOPが望んでいた仕事にコピーアンドペースト可能なワンライナー(ish)が欲しかった。

もちろん、セキュリティ設定が非常に低い場合を除いて、これらのmysqlコマンドでも資格情報を(2回)入力する必要があります。 (あるいはあなたのクレジットを含めるためにmysqlコマンドをエイリアスすることもできます。)

2
artfulrobot

ここにすべてのテーブルを削除するための便利な Jonathan Wattによるコメント を入れるだけです。

MYSQL="mysql -h Host -u USERNAME -pPASSWORD DB_NAME"
$MYSQL -BNe "show tables" | awk '{print "set foreign_key_checks=0; drop table `" $1 "`;"}' | $MYSQL
unset MYSQL

それは私を助け、私はそれが役に立つことを願っています

2

Phpではそれは同じくらい簡単です:

$pdo = new PDO('mysql:dbname=YOURDB', 'root', 'root');

$pdo->exec('SET FOREIGN_KEY_CHECKS = 0');

$query = "SELECT concat('DROP TABLE IF EXISTS ', table_name, ';')
          FROM information_schema.tables
          WHERE table_schema = 'YOURDB'";

foreach($pdo->query($query) as $row) {
    $pdo->exec($row[0]);
}

$pdo->exec('SET FOREIGN_KEY_CHECKS = 1');

YOURDBをあなたのデータベースの名前、そして明らかにuser/passに変更することを忘れないでください。

2
nsbucky

次のシェルスクリプトは、@ Dion Truterと@Wade Williamsによる答えを基に、実行しようとしているものを最初に表示し、Ctrl-Cを使用して中止する機会を与えた後、すべてのテーブルを削除します。

#!/bin/bash

DB_Host=xxx
DB_USERNAME=xxx
DB_PASSWORD=xxx
DB_NAME=xxx

CMD="mysql -sN -h ${DB_Host} -u ${DB_USERNAME} -p${DB_PASSWORD} ${DB_NAME}"

# Generate the drop statements
TMPFILE=/tmp/drop-${RANDOM}.sql
echo 'SET FOREIGN_KEY_CHECKS = 0;' > ${TMPFILE}
${CMD} $@ >> ${TMPFILE} << ENDD
    SELECT concat('DROP TABLE IF EXISTS \`', table_name, '\`;')
    FROM information_schema.tables
    WHERE table_schema = '${DB_NAME}';
ENDD
echo 'SET FOREIGN_KEY_CHECKS = 1;' >> ${TMPFILE}

# Warn what we are about to do
echo
cat ${TMPFILE}
echo
echo "Press ENTER to proceed (or Ctrl-C to abort)."
read

# Run the SQL
echo "Dropping tables..."
${CMD} $@ < ${TMPFILE}
echo "Exit status is ${?}."
rm ${TMPFILE}
1

これはかなり古い投稿ですが、ここでの答えはどれも私の意見では実際には答えていないので、私の投稿が人々に役立つことを願っています!

私はこの解決法を私にとって本当にうまくいく別の質問で見つけました:

mysql -Nse 'show tables' DB_NAME | while read table; do mysql -e "SET FOREIGN_KEY_CHECKS=0; truncate table \`$table\`" DB_NAME; done

データベースDB_NAME内のすべてのテーブルを実際に空にし、TRUNCATEコマンドラインを表示するだけではありません。

お役に立てれば!

1
mokk
DB="your database name" \
    && mysql $DB < "SET FOREIGN_KEY_CHECKS=0" \
    && mysqldump --add-drop-table --no-data $DB | grep 'DROP TABLE' | grep -Ev "^$" | mysql $DB \
    && mysql $DB < "SET FOREIGN_KEY_CHECKS=1"

単純明快(あってもいいです。)

気の利いた解決策ではないかもしれませんが、これは私を助け、私の一日を救った。

サーバーのバージョンで機能しました:5.6.38 MySQL Community Server(GPL)

私が従ったステップ:

 1. generate drop query using concat and group_concat.
 2. use database
 3. disable key constraint check
 4. copy the query generated from step 1
 5. enable key constraint check
 6. run show table

MySQLシェル

mysql> SYSTEM CLEAR;
mysql> SELECT CONCAT('DROP TABLE IF EXISTS `', GROUP_CONCAT(table_name SEPARATOR '`, `'), '`;') AS dropquery FROM information_schema.tables WHERE table_schema = 'emall_duplicate';
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| dropquery                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| DROP TABLE IF EXISTS `admin`, `app`, `app_meta_settings`, `commission`, `commission_history`, `coupon`, `email_templates`, `infopages`, `invoice`, `m_pc_xref`, `member`, `merchant`, `message_templates`, `mnotification`, `mshipping_address`, `notification`, `order`, `orderdetail`, `pattributes`, `pbrand`, `pcategory`, `permissions`, `pfeatures`, `pimage`, `preport`, `product`, `product_review`, `pspecification`, `ptechnical_specification`, `pwishlist`, `role_perms`, `roles`, `settings`, `test`, `testanother`, `user_perms`, `user_roles`, `users`, `wishlist`; |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> USE emall_duplicate;
Database changed
mysql> SET FOREIGN_KEY_CHECKS = 0;                                                                                                                                                   Query OK, 0 rows affected (0.00 sec)

// copy and paste generated query from step 1
mysql> DROP TABLE IF EXISTS `admin`, `app`, `app_meta_settings`, `commission`, `commission_history`, `coupon`, `email_templates`, `infopages`, `invoice`, `m_pc_xref`, `member`, `merchant`, `message_templates`, `mnotification`, `mshipping_address`, `notification`, `order`, `orderdetail`, `pattributes`, `pbrand`, `pcategory`, `permissions`, `pfeatures`, `pimage`, `preport`, `product`, `product_review`, `pspecification`, `ptechnical_specification`, `pwishlist`, `role_perms`, `roles`, `settings`, `test`, `testanother`, `user_perms`, `user_roles`, `users`, `wishlist`;
Query OK, 0 rows affected (0.18 sec)

mysql> SET FOREIGN_KEY_CHECKS = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW tables;
Empty set (0.01 sec)

mysql> 

enter image description here

0
Sanjay Khadka

この解決策は@SkyLeachの回答に基づいていますが、外部キーを持つテーブルを削除することをサポートしています。

echo "SET FOREIGN_KEY_CHECKS = 0;" > ./drop_all_tables.sql
mysqldump --add-drop-table --no-data -u user -p dbname | grep 'DROP TABLE' >> ./drop_all_tables.sql
echo "SET FOREIGN_KEY_CHECKS = 1;" >> ./drop_all_tables.sql
mysql -u user -p dbname < ./drop_all_tables.sql
0
pgmank