Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulate a DELETE CASCADE in MySQL?

Is it possible to predict the operations that follow a DELETE CASCADE automatically? In my software I would like to give the user a warning with details about the data that would be deleted then.

like image 567
user694971 Avatar asked May 17 '11 10:05

user694971


People also ask

How do I use cascade delete in MySQL?

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

Does MySQL support cascade delete?

ON DELETE CASCADE clause in MySQL is used to automatically remove the matching records from the child table when we delete the rows from the parent table. It is a kind of referential action related to the foreign key.

Does MySQL have Cascade?

CASCADE : Delete or update the row from the parent table and automatically delete or update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.


2 Answers

You can make a copy of the database and put triggers on the after delete

DELIMITER $$

CREATE TRIGGER ad_table1_each AFTER DELETE ON table1 FOR EACH ROW
BEGIN
  INSERT INTO log VALUES (null                 /*autoinc id*/
        , 'table1'                             /*tablename*/
        , old.id                               /*tableid*/
        , concat_ws(',',old.field1,old.field2  /*CSV's of fields*/
        , NOW()                                /*timestamp*/
        , 'delete');                           /*what action*/


  REPLACE INTO restore_table1 VALUES (old.id,
        , old.field1
        , old.field2
        , ... );

END $$

DELIMITER ;

The log table is just a table with the following fields:

id            integer autoincrement primary key
tablename     varchar(45)
table_id      integer
fields        varchar(6000)
delete_time   timestamp
action        enum('insert','update','delete')

If you do a SELECT @last_id:= max(id) FROM log before the delete cascade on the copy.
Then you can do a SELECT * FROM log WHERE id > @last_id
and get all the rows that will be deleted in the cascade.

After that you can use the restore_table1 to recreate the rows that were deleted in the cascade in the copy database.

like image 129
Johan Avatar answered Sep 20 '22 12:09

Johan


I think you could use Johan's trigger solution in combination with a transaction that you roll back. This avoids both the need for a second database and for the manual restore of the deleted entries.

  • add the trigger and the log table
  • for each attempted deletion start a transaction and delete the entries
  • present the information from the log to your user for approval
  • if the user agrees commit the transaction, otherwise rollback
like image 33
Stefan Avatar answered Sep 21 '22 12:09

Stefan