MySql "cannot update parent row" when I have "ON UPDATE CASCADE" - mysql

So, I am getting:
Error Code: 1451. Cannot delete or update a parent row: a foreign key
constraint fails (playground.Person, CONSTRAINT sk_Person_Parent
FOREIGN KEY (parent_id) REFERENCES Person (id) ON DELETE CASCADE
ON UPDATE CASCADE)
This is the simple table, referencing itself:
CREATE TABLE IF NOT EXISTS Person (
id int not null primary key,
name varchar(100) not null,
parent_id int null,
CONSTRAINT `sk_Person_Parent`
FOREIGN KEY (parent_id)
REFERENCES Person (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
as you see, there is "ON UPDATE CASCADE".
I insert 4 simple rows in it:
INSERT INTO Person(id, name, parent_id)
VALUES
(1, 'vasko', NULL),
(2, 'asdas', 1),
(3, 'ivo', 1),
(4, 'anton', 3);
so I have
1 - vasko
2 - asdasd
3 - ivo
4 - anton.
When i delete by id 1, all the records get wiped, because of the ON DELETE CASCADE. However, if I try to execute
UPDATE Person
SET id=10
WHERE id=1;
I get the given error. Any ideas?
(I am expecting vasil's id to become 10, and the parent_id of the next 2 rows to be updated to 10)

It is limitation in Mysql:
If ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the same table it has previously updated during the cascade, it acts like RESTRICT. This means that you cannot use self-referential ON UPDATE CASCADE or ON UPDATE SET NULL operations.
reference here

Related

Mysql on update cascade not working with tree table [duplicate]

So, I am getting:
Error Code: 1451. Cannot delete or update a parent row: a foreign key
constraint fails (playground.Person, CONSTRAINT sk_Person_Parent
FOREIGN KEY (parent_id) REFERENCES Person (id) ON DELETE CASCADE
ON UPDATE CASCADE)
This is the simple table, referencing itself:
CREATE TABLE IF NOT EXISTS Person (
id int not null primary key,
name varchar(100) not null,
parent_id int null,
CONSTRAINT `sk_Person_Parent`
FOREIGN KEY (parent_id)
REFERENCES Person (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
as you see, there is "ON UPDATE CASCADE".
I insert 4 simple rows in it:
INSERT INTO Person(id, name, parent_id)
VALUES
(1, 'vasko', NULL),
(2, 'asdas', 1),
(3, 'ivo', 1),
(4, 'anton', 3);
so I have
1 - vasko
2 - asdasd
3 - ivo
4 - anton.
When i delete by id 1, all the records get wiped, because of the ON DELETE CASCADE. However, if I try to execute
UPDATE Person
SET id=10
WHERE id=1;
I get the given error. Any ideas?
(I am expecting vasil's id to become 10, and the parent_id of the next 2 rows to be updated to 10)
It is limitation in Mysql:
If ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the same table it has previously updated during the cascade, it acts like RESTRICT. This means that you cannot use self-referential ON UPDATE CASCADE or ON UPDATE SET NULL operations.
reference here

How to update column with foreign key constraint within same table

In MySQL I want to update an ID-column of a table that is referenced in a foreign key constraint within that same table.
Example code:
CREATE TABLE A (
A_id int,
parent_A_id int,
PRIMARY KEY (A_id),
CONSTRAINT parent_A FOREIGN KEY (parent_A_id) REFERENCES A (A_id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO A VALUES (0, NULL), (1, 0);
Now I try to update the column A_id with
UPDATE A SET A_id = A_id + 1;
Unfortunately this throws an error:
Cannot delete or update a parent row: a foreign key constraint fails
I don't really understand why this fails and I can't find anything in the MySQL docs mentioning this not being allowed.
So, why does this not work?
And in the case that I don't just do a stupid mistake:
Is there any better way of doing such an update other than setting foreign_key_checks = 0 and doing everything by hand?
My problem with this would be that I'd like to use the ON UPDATE CASCADE to let the DB handle all foreign key updates for me.

Is there is any way to use ON DELETE CASCADE feature in adhoc basis using query when ON DELETE RESTRICT is defined?

I've created foreign key as ON DELETE RESTRICT but sometimes I need to delete child records along with deletion of the parent record. I can't use "ON DELETE CASCADE" because I need that restriction more often. So is there any way to change the behavior of the foreign key in runtime using any keyword or something in the query like below?
delete * from table1 where ID='3' CASCADE CHILD;
or
delete * from table1 where ID='3' SET foreign_key_behavior= 'ON DELETE CASCADE';
No, there's no syntax for forcing an ad hoc cascading delete if you didn't define the foreign key constraint with the ON DELETE CASCADE option.
Doing the DELETE against both tables in a join doesn't work in MySQL, despite the suggestion from #RaymondNijland in the comments.
Demo using MySQL 5.6:
mysql> create table foo ( id serial primary key );
mysql> create table bar (foo_id bigint unsigned not null,
foreign key (foo_id) references foo(id));
mysql> insert into foo values (1);
mysql> insert into bar values (1);
mysql> delete foo.*, bar.* from foo join bar on foo.id=bar.foo_id where foo.id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint
fails (`test`.`bar`, CONSTRAINT `bar_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES
`foo` (`id`))
You'll have to execute a separate delete for each child table, then a delete for the parent table.

SQL: Auto-reference table on update cascade

I have a table with a foreign key auto-referenced, like this:
CREATE TABLE user
(
id INT,
name VARCHAR(20),
ref INT,
PRIMARY KEY(id)
)ENGINE=InnoDB;
ALTER TABLE user
ADD FOREIGN KEY (ref) REFERENCES user(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
Then, I insert values in the table:
INSERT INTO user
VALUES(1, "User1", NULL), (2, "User2", 1), (3, "User3", 1), (4, "User4", 3);
SELECT * FROM user;
And I update a user to check if, when I update the id of a user, then the FK is updated on cascade:
UPDATE user
SET id = 5
WHERE id = 1;
But I get this error:
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails ('prueba'.'user', CONSTRAINT 'user_ibfk1' FOREIGN KEY ('ref') REFERENCES 'user' ('id') ON UPDATE CASCADE)
Can anyone say me what I'm doing wrong? Thank you.
see the dev document. Your self-referential "ON UPDATE CASCADE" acts like "ON UPDATE RESTRICT".
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
If ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the same table it has previously updated during the cascade, it acts like RESTRICT. This means that you cannot use self-referential ON UPDATE CASCADE or ON UPDATE SET NULL operations. This is to prevent infinite loops resulting from cascaded updates. A self-referential ON DELETE SET NULL, on the other hand, is possible, as is a self-referential ON DELETE CASCADE. Cascading operations may not be nested more than 15 levels deep.

MySQL After Insert Trigger to table with FK to first table

This is my current Trigger:
CREATE DEFINER=`root`#`localhost` TRIGGER `setaccessrole` AFTER INSERT ON `user` FOR EACH ROW BEGIN
INSERT INTO user_role_linker (user_id, role_id) values (last_insert_id(), 2);
END
user_role_linker.user_id is FK to user.id, I want an insert into user_role_linker including the last inserted autoincremented ID + user_role = 2, but I get:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`database`.`user_role_linker`, CONSTRAINT `FK_61117899A76ED395` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))
edit:
I had to use "NEW.id" instead of last_insert_id().
This works.
edit: I had to use "NEW.id" instead of last_insert_id(). This works.