it-swarm.asia

الخلية إسقاط جميع الجداول ، وتجاهل المفاتيح الخارجية

هل هناك طريقة سهلة لطيفة لإسقاط جميع الجداول من قاعدة بيانات MySQL ، مع تجاهل أي قيود مفتاح خارجي قد تكون هناك؟

330
bcmcfc

لقد وجدت المجموعة التي تم إنشاؤها من عبارات الإسقاط مفيدة ، وأوصي بتعديل هذه:

  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 بتسهيل عملية النقل. في MySQL 5.5 ، لا يفعلون شيئًا."

لذلك ، لكي تعمل عبارات الإسقاط إذا كنت بحاجة إلى:

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.

378
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`;
85
Jean-François Beauchamp

يتضمن كل نهج أعلاه الكثير من العمل أكثر من هذا 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
31
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.


أو خلاف ذلك ، فإن إجابة Dion المقبولة أبسط ، إلا أنك تحتاج إلى تنفيذها مرتين ، أولاً للحصول على الاستعلام ، والثانية لتنفيذ الاستعلام. لقد قدمت بعض علامات التجزئة السخيفة للهروب من الأحرف الخاصة في أسماء الجداول والجداول.

  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
Pablo Santa Cruz

توصلت إلى هذا التعديل على إجابة 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';

يؤدي هذا إلى إرجاع الشيء بالكامل في حقل واحد ، بحيث يمكنك النسخ مرة واحدة وحذف جميع الجداول (استخدم Copy Field Content (unquoted) في Workbench). إذا كان لديك الكثير من الجداول ، فقد تضغط بعض القيود على GROUP_CONCAT(). إذا كان الأمر كذلك ، فقم بزيادة الحد الأقصى لمتغير 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 (أو أي نظام آخر يدعم المواسير ، الصدى و grep) ، يمكنك القيام بذلك بسطر واحد:

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

بطانة واحدة لإسقاط جميع الجداول من قاعدة بيانات معينة:

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

في Linux Shell مثل bash/zsh:

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"

سيؤدي ذلك إلى إنشاء الأوامر ، ثم توجيهها على الفور إلى مثيل عميل ثانٍ يؤدي إلى حذف الجداول.

بالطبع يتم نسخ البت الذكي من الإجابات الأخرى هنا - أردت فقط أن يكون هناك نسخة واحدة يمكن نسخها ولصقها (ish) لكي تقوم بالفعل القيام بها المهمة التي أرادها البروتوكول الاختياري.

ملاحظة بالطبع سيتعين عليك وضع بيانات الاعتماد الخاصة بك في (مرتين) في أوامر mysql هذه ، أيضًا ، ما لم يكن لديك إعداد أمان منخفض جدًا. (أو يمكنك تسمية أمر mysql الخاص بك لتضمين أرصدةك.)

2
artfulrobot

ضع هنا بعض النصائح المفيدة التي أدلى بها جوناثان وات لإسقاط جميع الجداول

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
Pavel.Solovyenko

ينقلني غوغلينغ حول هذا الموضوع دائمًا إلى هذا السؤال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`;
2
Sergey Alaev

في 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 إلى اسم قاعدة البيانات الخاصة بك ، ومن الواضح أن المستخدم/تمرير.

2
nsbucky

بناءً على إجابة كل منDion Truter و @ Wade Williams ، سوف يقوم البرنامج النصي Shell التالي بإسقاط جميع الجداول ، بعد أن يعرض أولاً ما هو على وشك التشغيل ، ويمنحك فرصة للإجهاض باستخدام 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} [email protected] >> ${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} [email protected] < ${TMPFILE}
echo "Exit status is ${?}."
rm ${TMPFILE}
1
Philip Callender

هذا منشور قديم إلى حد ما ، لكن أياً من الإجابات هنا أجبت عن السؤال في رأيي ، لذلك آمل أن يساعد منشوري الأشخاص!

لقد وجدت هذا الحل على سؤال آخر يعمل بشكل جيد بالنسبة لي:

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"
0
Ernestas Stankevičius

بسيطة وواضحة (قد يكون).

قد لا يكون حلا خياليا ، ولكن هذا عملت لي وحفظت يومي.

عملت من أجل إصدار الخادم: 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 Shell

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