Reputation: 2448
My database is MySQL with foreign key management. It has 2 tables :
Table1 :
|id|foreignKeyToTable2|data...|
Table2 :
|id|foreignKeyToTable1|data...|
I want to delete a couple of these lines but when I delete one of them I have the meaningful foreign key error.
How can I delete the couple of lines in one time?
Am I forced to disable foreign key checks?
I need both of the keys because there is actually 2 relations. Lets be more practical :
Tables are :
DDL
|id|name|defaultValue (FK delete cascade)|
Value
|id|name|DDLiD (FK)|
Following your answers, I added a DELETE CASCADE to the DDL table. But I still have a FK error .
Cannot delete or update a parent row: a foreign key constraint fails (Value, CONSTRAINT fk_Value_DDL FOREIGN KEY (DDL) REFERENCES DDL (id) ON DELETE NO ACTION ON UPDATE NO ACTION)
I don't want to add a delete cascade on the Value table because i want to be able to delete a value.
Upvotes: 3
Views: 4357
Reputation: 2129
lets assume we have two tables foo has Id | Name | carId
bar has Id | Color
to delete both tables
delete bar where id in (select f.Id from foo f inner join boo b on b.Id = f.Id where f.carId = 22)
Upvotes: 0
Reputation: 548
Using a cascade delete / update should handle the necessary.
I've got an alternative suggestion though, which is more of an architectural solvent/resolve.
Status | BIT | Default(1)
PrimaryTable.Status = 1
when joining with the primary tableUpvotes: 1
Reputation: 3189
You have two options here:
ON DELETE CASCADE
. The second option is my prefered one, because a database user is informed about the usage in the other table and can then decide to use a transaction to remove data from both rows.
Also, one usage scenario of a 1:1 relation is to allow different permissions on both tables. When using delete cascade I don't know if these are checked.
EDIT
After I was pointed that MySQL is handling foreign key checking not as stated in the SQL standards, my second option is changed to:
2. Because MySQL does not support deferred checking of foreign key constraints while using transactions (this is a deviation from SQL standards), you need to disable foreign key checks for the delete statements:
SET foreign_key_checks = 0;
DELETE ...;
SET foreign_key_checks = 1;
Upvotes: 4
Reputation: 2448
The solution I found is to remove one of the foreign keys and manage it with the application. tables are now :
DDL
|id|name|defaultValue|
Value
|id|name|DDLiD (FK)|
defaultValue is an id of the table Value but not a foreign key...
When I want to delete, first I delete the values, then I delete the DDL.
Thank you all.
Nicolas.
Upvotes: 0
Reputation: 76567
You need to set the foreign key to cascade mode:
CREATE TABLE table1 (
fields....
FOREIGN KEY fk_name(fk_to_table2) REFERENCES table2.id
ON DELETE CASCADE ON UPDATE CASCADE <<--- Change this.
If you change the table layout like this, MySQL will not block, but instead propagate the deletion.
Note that if you have a 1-to-1 relation, you do not have a separate foreign key field, but your primary key links to another primary key, like so:
CREATE TABLE t1 (
id UNSIGNED INTEGER AUTO_INCREMENT PRIMARY KEY,
otherfields....,
) ENGINE = InnoDB; <<-- no foreign key in T1, because t1 is the master.
CREATE TABLE t2 (
id UNSIGNED INTEGER AUTO_INCREMENT PRIMARY KEY,
otherfields....,
FOREIGN KEY fk_t1_id(id) REFERENCES t1(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB; <<-- t2 follows t1.
Now you enforce a 1-1 relationship, instead of a 1-n.
Note that setting NO ACTION
is the same as RESTRICT
: http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
NO ACTION: A keyword from standard SQL. In MySQL, equivalent to RESTRICT. InnoDB rejects the delete or update operation for the parent table if there is a related foreign key value in the referenced table. Some database systems have deferred checks, and NO ACTION is a deferred check. In MySQL, foreign key constraints are checked immediately, so NO ACTION is the same as RESTRICT.
Upvotes: 2