Issiue with ON DELETE CASCADE? - mysql

I have a question about ON DELETE CASCADE, i have made thise tables as an example.
CREATE TABLE shop_articles(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
description TEXT
);
CREATE TABLE shop_articles_images(
id INT AUTO_INCREMENT PRIMARY KEY,
article_id INT,
description VARCHAR(255),
image VARCHAR(255),
FOREIGN KEY (article_id) REFERENCES shop_articles (id)
);
In order to delete all the data affiliated with the main table, i am using this ALTER TABLE command after adding the tables.
ALTER TABLE shop_articles_images
ADD CONSTRAINT shop_articles_images_ibf5
FOREIGN KEY (article_id) REFERENCES shop_articles (id)
ON DELETE CASCADE;
It seams alltough this have been added i cant delete rows from the main table, i dont want to manually delete the other affiliated tables, but delete it when delete from the main table.
Any one have experience with this, or can see what i do wrong here? does this altertable reset when the mysql server is restarted?

I think you have some confusion about how ON DELETE CASCADE works. If your engine is MyISAM, which does not enforce foreign keys, then no cascading deletes will happen. If your engine is InnoDB, then if you delete a record from the main table shop_articles then any records in shop_articles_images which are linked to the main table via a key relationship will also be deleted.

Related

Correct way to remove entry from a SQL table along with the relations

If we have TableA and TableB related by TableAB where TableAB has foreign keys for the first two table, then what's the go-to way of deleting an entry from TableA? Up to now if used a property such as IsActive with a bit to describe if the entry is still valid. However, that makes it a little problematic when there are "ghost entries" in the relation tables, such as TableAB.
How should I proceed?
One chaining table in question.
CREATE TABLE EntradaContadorCliente (
ClaveECC int AUTO_INCREMENT not null,
ClaveCliente int not null,
ClaveContador int not null,
ClaveEntrada int not null,
PRIMARY KEY (ClaveECC),
FOREIGN KEY (ClaveCliente) REFERENCES Cliente(ClaveCliente),
FOREIGN KEY (ClaveContador) REFERENCES Contador(ClaveContador),
FOREIGN KEY (ClaveEntrada) REFERENCES EntradaBitacora(ClaveEntrada)
);
Since TableA and TableB related by TableAB; which means TableAB is a chaining table. One way is to use ON DELETE CASCADE for cascading the delete operation on primary table.
Alternative is to, manually delete the entries from your chaining table once the entry has been deleted from primary table.
You can use a ALTER statement to re-create the FK constraint like
ALTER TABLE `TableAB` DROP FOREIGN KEY FK_KEY_Test;
ALTER TABLE `TableAB` ADD CONSTRAINT FK_KEY_Test FOREIGN KEY ('some_column')
REFERENCES `TableA` ('Test_column1') ON UPDATE CASCADE ON DELETE CASCADE;
From MySQL Documentation:
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.
first you disable all foreign key with:-
alter table table_name
nocheck constraint fk_constraint
then you delete data in parent table.

How to make foreign key update based on parent

I have two tables, and I've made a relation using the Designer between the id column of my first table to the user_id column of my second table. Where and how do I add code or do something so that when, for example, the parent (id) is deleted, the user_id values which correspond to the deleted id will also be deleted? I tried deleting one of the registered ids, but the corresponding rows in the child table didn't get deleted.
I've done some searching, but I'm still very confused.
Thank you.
Note: I'm experimenting with MySQL and PHP, and this is for a little blog I'm making.
Please add an ON DELETE referential action to the foreign key constraint.
More details could be found here:
https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
For your case, ON DELETE CASCADE should be fine.
set id from first table as primary key
CREATE TABLE tbl_first(id INT PRIMARY KEY AUTO_INCREMENT, name varchar(20))
create your second table as tbl_second
CREATE TABLE tbl_second(id INT PRIMARY KEY AUTO_INCREMENT, fk_id int)
add constraint like this:
alter table tbl_second
add constraint fk_first
foreign key tbl_second(fk_id)
references tbl_first(id)
on delete cascade
it seem SQL Server and mySql are a little different, but it should work, i test it in mySQL

Foreign Key Tables Updates

I just started learning SQL so I am a bit confused.
If I have Table A that has a primary key : CustomerID & Table B with foreign key CustomerID
I added the foreign key constraint by using CASCADE so that the foreign key should update or delete automatically when primary key is deleted or updated.
However, it only works for delete. When I add a new record in the primary field table, that record is not shown in the foreign key table, why is that ?
Corresponding rows are updated or deleted in the referencing table
when that row is updated or deleted in the parent table. CASCADE
cannot be specified if a timestamp column is part of either the
foreign key or the referenced key. ON DELETE CASCADE cannot be
specified for a table that has an INSTEAD OF DELETE trigger. ON UPDATE
CASCADE cannot be specified for tables that have INSTEAD OF UPDATE
triggers.
As mention in MSDN. They have mentioned the only update and delete operation of primary key table will affect the Foreign key table's column. If any insert made to primary key, it will not affected the foreign key. Since the Main objective in primary key and foreign key relationship
"An each every record is available in the foreign key table, it should contain corresponding record should be present in the primay key table and vice versa is not applicable".
If you insert any record to foreign key table that it will throws foreign referential integrity error. It will not allows you to insert a record in the foreign table unless and until you will corresponding record in the primary key table.
for information take look in following in MSDN links
http://msdn.microsoft.com/en-us/library/ms179610.aspx
Note:
if you want to achieve this functionality then you have write a logic in Stored procedure or trigger.
No,is not automatic add in your foreign key table , it's not make sense , for example if you have two table ,"City" and "People" , People in the City , so there must be a FK refer for People , if you add record in City e.g. New York , How is database know who's need to insert to People table?How many people? , and what this people properties? e.g. People Name?
So database can't do that automatic , you have to do it manually!

tables related with foreign key are synched with each other

I am using phpmyadmin for mysql. I have 4 tables project1, project2, project3 and combine table. suppose combine table is connected to all other tables with the foreign keys and we add some data with the help of some background script to project1, prject2, and project3 tables. Is there any way to update the corresponding foreign keys in the combine table automatically ( without manually updating the record). I am using a yii framework for the GUI.
Please suggest some way as I am new to mysql and yii framework.
http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
Not fully understanding your question but I think you are referring to ON DELETE and ON UPDATE.
ON DELETE & ON UPDATE options
CASCADE
SET NULL
NO ACTION
RESTRICT
ON DELETE & ON CASCADE are placed as constraints in the FK table and they occur when parent ID is either deleted or updated.
So if you change an id within the projects table and you wish for this change to be reflected in the combine table, you would use ON UPDATE CASCADE.
As a side note, why do you have 4 tables? I can only see the need for 2 tables.
Please note that SQL below may not be syntactically correct.
CREATE TABLE tbl_projects (
id integer NOT NULL PRIMARY KEY AUTO INCREMENT,
name varchar(255),
...
...
);
Method 1 creating a row for each project in the combine table:
CREATE TABLE tbl_combine (
id integer NOT NULL PRIMARY KEY AUTO INCREMENT,
project_id integer,
...
CONSTRAINT `FK_combine_project`
FOREIGN KEY (`project_id`)
REFERENCES `tbl_project` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
);
Method 2:
CREATE TABLE tbl_combine (
id integer NOT NULL PRIMARY KEY AUTO INCREMENT,
project1_id integer,
project2_id integer,
project3_id integer,
...
CONSTRAINT `FK_combine_project1`
FOREIGN KEY (`project1_id`)
REFERENCES `tbl_project` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `FK_combine_project2`
FOREIGN KEY (`project2_id`)
REFERENCES `tbl_project` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `FK_combine_project3`
FOREIGN KEY (`project3_id`)
REFERENCES `tbl_project` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
);
You can also do this via GUI in phpmyadmin by setting the foreign keys as an index by clicking a button, then going to the table relation view and choosing your options.
Hope this helps - I have attached an phpmyadmin image for you to see.

MySQL: delete a row ignoring foreign key constraint

so I am working on a few tables and there are some data inconsistency between them... One or two tables have a foreign key constraint on a particular table (call it table X), but that table has multiple rows with the foreign key column.
What I want to do is to remove the duplicated rows in table X, but the foreign key constraint is preventing me from doing this. Is there a way to force delete the rows while ignoring the foreign key constraint since I know what I'm doing?
SET foreign_key_checks = 0;
That will prevent MySQL from checking foreign keys. Make sure to set it back to 1 when you are done though.
Also, you could always drop the foreign key and then add it later if you wanted to only affect a singular key
ALTER TABLE tableName DROP FOREIGN KEY fk;
Simply execute as follows:
Disable foreign key check
SET foreign_key_checks = 0;
Delete your records
DELETE FROM table_name WHERE {conditions};
Enable foreign key check
SET foreign_key_checks = 1;
Credit: https://www.knowledgewalls.com/johnpeter/books/mysql/how-to-ignore-constraints-while-insertupdate-or-delete-records-in-mysql
As some people already pointed out, ignoring a restricting foreign key leaves you with database inconsistencies. Preventing DELETEs is something you want in such cases.
You should better delete depending rows prior to the main query:
DELETE FROM cities WHERE country_id=3;
-- Afterwards you delete rows from the parent table without error:
DELETE FROM countries WHERE country_id=3;
Or, even better, change the foreign key once, so it does the deletion automatically (cascading):
ALTER TABLE cities DROP FOREIGN KEY `fk.cities.country_id`;
ALTER TABLE cities ADD CONSTRAINT `fk.cities.country_id` FOREIGN KEY (country_id)
REFERENCES countries (id) ON UPDATE CASCADE ON DELETE CASCADE;
-- From now on, just delete from the parent table:
DELETE FROM countries WHERE country_id=3;
To expand on the accepted answer, you have to specify the constraint name after DROP FOREIGN KEY
You can check the constraint name by issuing SHOW CREATE TABLE.
> SHOW CREATE TABLE tbl_name
Create Table: CREATE TABLE `tbl_name` (
`id` int(11) DEFAULT NULL,
`foo_id` int(11) DEFAULT NULL,
CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`foo_id`)
)
In this case, "foo_ibfk_1" is the constraint name. So you can write:
ALTER TABLE tableName DROP FOREIGN KEY foo_ibfk_1;