865

Why doesn't a TRUNCATE on mygroup work? Even though I have ON DELETE CASCADE SET I get:

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (mytest.instance, CONSTRAINT instance_ibfk_1 FOREIGN KEY (GroupID) REFERENCES mytest.mygroup (ID))

drop database mytest;
create database mytest;
use mytest;

CREATE TABLE mygroup (
   ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY
) ENGINE=InnoDB;

CREATE TABLE instance (
   ID           INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   GroupID      INT NOT NULL,
   DateTime     DATETIME DEFAULT NULL,

   FOREIGN KEY  (GroupID) REFERENCES mygroup(ID) ON DELETE CASCADE,
   UNIQUE(GroupID)
) ENGINE=InnoDB;
0

16 Answers 16

1643

Yes you can:

SET FOREIGN_KEY_CHECKS = 0;

TRUNCATE table1;
TRUNCATE table2;

SET FOREIGN_KEY_CHECKS = 1;

With these statements, you risk letting in rows into your tables that do not adhere to the FOREIGN KEY constraints.

12
  • 43
    do we have to set SET FOREIGN_KEY_CHECKS=1; again afterwards?
    – vinc3m1
    Commented Apr 9, 2012 at 21:29
  • 103
    No, you don't. The setting is only valid during the connection. As soon as you disconnect, the next connection will have it set back to 1.
    – Pelle
    Commented Jun 27, 2012 at 8:07
  • 8
    This does not apply the 'ON DELETE' event in the referenced table, so this is not a complete answer.
    – SlimDeluxe
    Commented Oct 16, 2012 at 9:09
  • 8
    If using in PHPMYADMIN, this works only if you use all the transactions in the same SQL window (separated by a ;). This is because each fresh web SQL call will reset the FOREIGN_KEY_CHECKS to 1.
    – Sablefoste
    Commented Oct 7, 2013 at 21:17
  • 1
    Here is a very good way to find orphaned foreign keys (restore data integrity) in case you are interested http://stackoverflow.com/a/12085689/997776
    – sanya
    Commented Feb 4, 2015 at 13:27
1246

You cannot TRUNCATE a table that has FK constraints applied on it (TRUNCATE is not the same as DELETE).

To work around this, use either of these solutions. Both present risks of damaging the data integrity.

Option 1:

  1. Remove constraints
  2. Perform TRUNCATE
  3. Delete manually the rows that now have references to nowhere
  4. Create constraints

Option 2: suggested by user447951 in their answer

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;
25
  • 58
    @barjonah: actually, it might break data integrity (see stackoverflow.com/questions/5452760/…). So, what you call "light" in the real world is considered to be a bad practice. PS: thanks for the downvote
    – zerkms
    Commented Nov 1, 2012 at 2:59
  • 2
    Here is a very good way to find orphaned foreign keys (restore data integrity) http://stackoverflow.com/a/12085689/997776
    – sanya
    Commented Feb 4, 2015 at 13:26
  • 3
    @Dung disabling foreign key checks is only allowed in the development period. It breaks any existing relationships. zerkms is 100% right about data integrity. You can not disable foreign key checks on a working database unless you're planning to empty it completely (or at least all related tables)
    – NoobishPro
    Commented Oct 4, 2016 at 3:15
  • 2
    @Kamlesh it's not my solution, I adviced to not do it that barbaric way.
    – zerkms
    Commented Nov 13, 2019 at 20:14
  • 1
    @zerkms - apologies if I was nto clear, of course the MySQL implementation of truncate and delete are different. What I am saying is truncate implementation could be better - not make it same as delete statement. If the truncate operation does not violate FK constraints (i.e. the child tables are empty), there is no reason to error it saying FK violation - as there would not be any! This is how other RDBMS truncate implementation work.
    – AshkaliD
    Commented Jun 1, 2021 at 8:08
245

I would simply do it with :

DELETE FROM mytest.instance;
ALTER TABLE mytest.instance AUTO_INCREMENT = 1;
6
  • 8
    Smart. When you want to delete all records anyway, you might as well reset the auto increment.
    – winkbrace
    Commented May 21, 2015 at 8:53
  • 14
    This is obviously the best way to do it. No risk of losing constraints, just plain delete. It's worth noticing that DELETE performs slower than TRUNCATE. But since this action is usually performed only rarely, this does not matter.
    – phil294
    Commented Sep 12, 2015 at 18:52
  • 3
    This is good if that's all you want to do, but DELETE can be absolutely brutal if you have too many rows - since it hits the logs, whereas TRUNCATE just rips the data out. Really depends on use case.
    – Jeff
    Commented Feb 16, 2016 at 4:13
  • 2
    when I'm using delete statement, it report error 1175: You are using safe update mode, just add SET SQL_SAFE_UPDATES = 0; then it's fine
    – user4985526
    Commented Apr 20, 2016 at 2:41
  • 3
    When using this solution, it reports error 1175: You are using safe update mode,... change delete clause to DELETE FROM mydb.mytable where id != 0 makes it perfect. Commented Jul 17, 2018 at 7:08
45

Tested on MYSQL Database

Solution 1:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE table1;

Solution 2:

DELETE FROM table1;
ALTER TABLE table1 AUTO_INCREMENT = 1;
TRUNCATE table1;

This works for me. I hope, this will help you also. Thanks for asking this question.

3
  • 1
    Solution 2 worked for me in phpMyAdmin, but without TRUNCATE table1;
    – Novasol
    Commented May 3, 2021 at 9:08
  • Solutions depend on mysql version that's why I posted 2 solutions. Happy to share and help :)
    – Kamlesh
    Commented May 4, 2021 at 6:27
  • @Novasol Yes, you are right, it works but if you run TRUNCATE table1; command then mysql table index will be set to 0 internally automatically which will take less time when you make join this table1 with any other table/tables.
    – Kamlesh
    Commented May 4, 2021 at 6:30
43

Easy if you are using phpMyAdmin.

Just uncheck Enable foreign key checks option under SQL tab and run TRUNCATE <TABLE_NAME>

enter image description here

2
  • Perfect Answer for phpMyAdmin users. Commented Aug 13, 2022 at 6:37
  • 1
    Ahh, thx, nothing else works in phpmyadmin xd
    – danigore
    Commented Jul 3, 2023 at 9:12
24

you can do

DELETE FROM `mytable` WHERE `id` > 0
5
  • 1
    I tried it bur, the following error appeared:Error Code: 1142. DELETE command denied to user 'root'@'localhost' for table 'mytable'
    – AAEM
    Commented Jul 10, 2018 at 20:37
  • 3
    or just DELETE FROM mytable Commented Aug 27, 2019 at 13:10
  • 3
    This wouldn't reset the auto increment.
    – nice_dev
    Commented Sep 19, 2019 at 10:36
  • 2
    you can most certainly do this. However if you have a table with seven million records, go take a lunch while you're waiting.
    – John Lord
    Commented Aug 7, 2020 at 15:31
  • @AAEM Could be a few problems. Usually means you need to grant delete permissions to your "root" user on your database, or run flush privileges. See here: stackoverflow.com/questions/4767055/…
    – Kyle
    Commented Sep 13, 2021 at 15:21
14

As per MySQL documentation, TRUNCATE cannot be used on tables with foreign key relationships. There is no complete alternative AFAIK.

Dropping the constraint still does not invoke the ON DELETE and ON UPDATE. The only solution I can ATM think of is to either:

  • delete all rows, drop the foreign keys, truncate, recreate keys
  • delete all rows, reset auto_increment (if used)

It would seem TRUNCATE in MySQL is not a complete feature yet (it also does not invoke triggers). See comment

2
  • 8
    A note on your point about MySQL's TRUNCATE being incomplete - truncate isn't supposed to invoke triggers etc. If it did, it would just be the same as DELETE! It's row-agnostic, hence it's unable to perform row-related operations (like invoking triggers or examining foreign keys). It works in the same way in Oracle and Sql Server. Commented Feb 18, 2015 at 5:02
  • Why nobody mentions that TRUNCATE will reset the PRIMARY KEY? With DELETE it won't reset the PRIMARY KEY so your first record will have ID like 325579 which is strange. TRUNCATE shouldn't fail this way IMHO. Truncate is reset the table so it should reset no matter what.
    – Peter
    Commented Jan 31, 2021 at 16:32
8

While this question was asked I didn't know about it, but now if you use phpMyAdmin you can simply open the database and select the table(s) you want to truncate.

  • At the bottom there is a drop down with many options. Open it and select Empty option under the heading Delete data or table.
  • It takes you to the next page automatically where there is an option in checkbox called Enable foreign key checks. Just unselect it and press the Yes button and the selected table(s) will be truncated.

Maybe it internally runs the query suggested in user447951's answer, but it is very convenient to use from phpMyAdmin interface.

0
7

Answer is indeed the one provided by zerkms, as stated on Option 1:

Option 1: which does not risk damage to data integrity:

  1. Remove constraints
  2. Perform TRUNCATE
  3. Delete manually the rows that now have references to nowhere
  4. Create constraints

The tricky part is Removing constraints, so I want to tell you how, in case someone needs to know how to do that:

  1. Run SHOW CREATE TABLE <Table Name> query to see what is your FOREIGN KEY's name (Red frame in below image):

    enter image description here

  2. Run ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign Key Name>. This will remove the foreign key constraint.

  3. Drop the associated Index (through table structure page), and you are done.

to re-create foreign keys:

ALTER TABLE <Table Name>
ADD FOREIGN KEY (<Field Name>) REFERENCES <Foreign Table Name>(<Field Name>);
0
4

Another workaround is delete all rows in the table then reset auto-increment columns:

delete from table_name where 1

then Run:

ALTER TABLE table_name AUTO_INCREMENT = 1
4

How to truncate a foreign key constrained table? This illustration will demonstrate how to solve mysql error when truncating a table with foreign key constraint. If you are using PHPMYADMIN, it is very easy to truncate a table with foreign key constraint.

  1. Login to PHPMYADMIN and click the table you want to truncate.
  2. Then go to SQL tab Place your code to truncate the table in the SQL Editor example truncate table students; Replace students with the name of the table.
  3. At the bottom of the editor untick the "Enable foreign key checks" checkbox as shown below:

enter image description here

It will work like magic.

3

if you are using laravel migrations, you can do this using facades helpers

prefer to use Eloquent objects, answer the "Eloquent" way

 Schema::disableForeignKeyConstraints();
 Teacher::truncate();
 Schema::enableForeignKeyConstraints();

In Laravel 7 and 8, for compatibility across 4 databases (MySql, Postgres, SQLite and SqlServer) and no Eloquent, you can use:

Schema::disableForeignKeyConstraints();
    DB::table('teachers')->truncate();
Schema::enableForeignKeyConstraints();
1
  • Pretty handy trick. Thanks!
    – Adsy2010
    Commented Sep 21, 2023 at 7:58
0

Getting the old foreign key check state and sql mode are best way to truncate / Drop the table as Mysql Workbench do while synchronizing model to database.

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;`
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

DROP TABLE TABLE_NAME;
TRUNCATE TABLE_NAME;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
0

If the database engine for tables differ you will get this error so change them to InnoDB

ALTER TABLE my_table ENGINE = InnoDB;
0

Just use CASCADE

TRUNCATE "products" RESTART IDENTITY CASCADE;

But be ready for cascade deletes )

1
  • 11
    The OP tagged MySQL. While this is valid in Postgres, it is incorrect in MySQL.
    – Peter
    Commented Sep 26, 2019 at 9:30
0

Before crud operation query and truncating table, we use a safe query at that point.

For a crude operation like deleting a query, you can write this command.

SET SQL_SAFE_UPDATES = 0;

after this that query can rewrite zero to one for safe query.

 SET SQL_SAFE_UPDATES = 1;

For truncate tables, we can write the command below before truncating the query.

SET FOREIGN_KEY_CHECKS = 0;

after that query can rewrite zero to one for safe query.

 SET FOREIGN_KEY_CHECKS = 1;

Not the answer you're looking for? Browse other questions tagged or ask your own question.