外键引用两个 child table 到 parent table & grandchild table 到两个 child tables,更新parent table 外键约束失败
Foreign keys reference two child tables to parent table & grandchild table to the two child tables, updating parent table foreign key constraint fails
我创建了 4 个 tables - p_table
、c_table
、c2_table
和 cc_table
。 table结构如下:-
SHOW CREATE TABLE p_table;
| p_table | CREATE TABLE `p_table` (
`p_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c_table;
| c_table | CREATE TABLE `c_table` (
`c_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c_table_id`),
KEY `i_c_table` (`p_table_id`),
CONSTRAINT `fk_p_table` FOREIGN KEY (`p_table_id`) REFERENCES `p_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c2_table;
| c2_table | CREATE TABLE `c2_table` (
`c2_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c2_table_id`),
KEY `i_c2_table` (`p_table_id`),
CONSTRAINT `fk2_p_table` FOREIGN KEY (`p_table_id`) REFERENCES `p_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE cc_table;
| cc_table | CREATE TABLE `cc_table` (
`cc_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`cc_table_id`),
KEY `i_cc_table` (`p_table_id`),
CONSTRAINT `fk_c2_table` FOREIGN KEY (`p_table_id`) REFERENCES `c2_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
此处,table c_table
的第 p_table_id
列和 table c2_table
的第 p_table_id
列引用了 p_table_id
列table p_table
通过外键。
同样,table cc_table
的第 p_table_id
列引用了 table c_table
的第 p_table_id
列和 p_table_id
列table c2_table
通过外键。
所有参考中的参考选项都是-
ON DELETE RESTRICT
ON UPDATE CASCADE
这是某种 1-2-1 连锁结构。
现在,我按如下方式填充 4 tables :-
SELECT * FROM p_table;
+------------+----------+
| p_table_id | value |
+------------+----------+
| 1 | p_value1 |
| 2 | p_value2 |
| 3 | p_value3 |
| 4 | p_value4 |
| 5 | p_value5 |
+------------+----------+
SELECT * FROM c_table;
+------------+------------+-----------+
| c_table_id | p_table_id | value |
+------------+------------+-----------+
| 1 | 1 | c_value11 |
| 2 | 2 | c_value21 |
| 3 | 2 | c_value22 |
| 4 | 3 | c_value31 |
| 5 | 3 | c_value32 |
| 6 | 3 | c_value33 |
| 7 | 4 | c_value41 |
| 8 | 4 | c_value42 |
| 9 | 4 | c_value43 |
| 10 | 4 | c_value44 |
| 11 | 5 | c_value51 |
| 12 | 5 | c_value52 |
| 13 | 5 | c_value53 |
| 14 | 5 | c_value54 |
| 15 | 5 | c_value55 |
+------------+------------+-----------+
SELECT * FROM c2_table;
+-------------+------------+-----------+
| c2_table_id | p_table_id | value |
+-------------+------------+-----------+
| 1 | 1 | c_value11 |
| 2 | 2 | c_value21 |
| 3 | 2 | c_value22 |
| 4 | 3 | c_value31 |
| 5 | 3 | c_value32 |
| 6 | 3 | c_value33 |
| 7 | 4 | c_value41 |
| 8 | 4 | c_value42 |
| 9 | 4 | c_value43 |
| 10 | 4 | c_value44 |
| 11 | 5 | c_value51 |
| 12 | 5 | c_value52 |
| 13 | 5 | c_value53 |
| 14 | 5 | c_value54 |
| 15 | 5 | c_value55 |
+-------------+------------+-----------+
SELECT * FROM cc_table;
+-------------+------------+------------+
| cc_table_id | p_table_id | value |
+-------------+------------+------------+
| 1 | 1 | cc_value11 |
| 2 | 1 | cc_value12 |
| 3 | 1 | cc_value13 |
| 4 | 1 | cc_value14 |
| 5 | 1 | cc_value15 |
| 6 | 2 | cc_value21 |
| 7 | 2 | cc_value22 |
| 8 | 2 | cc_value23 |
| 9 | 2 | cc_value24 |
| 10 | 3 | cc_value31 |
| 11 | 3 | cc_value32 |
| 12 | 3 | cc_value33 |
| 13 | 4 | cc_value41 |
| 14 | 4 | cc_value42 |
| 15 | 5 | cc_value51 |
+-------------+------------+------------+
现在,我尝试更新 table p_table
中的一个值。预期的行为是所有 child table 的相应值将得到更新。
但是,我收到以下错误 -
UPDATE p_table
-> SET p_table_id = 3333 WHERE p_table_id = 3;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`constraints`.`cc_table`, CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE)
现在,我尝试删除链接 cc_table
和 c2_table
的外键 fk_c2_table
。所有 child table 最终都链接到 parent table p_table
.
ALTER TABLE cc_table
-> DROP FOREIGN KEY fk_c2_table;
现在,我尝试更新 table p_table
中的一个值,我成功了。
UPDATE p_table
-> SET p_table_id = 3333 WHERE p_table_id = 3;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0
三个 child table 中的相应值 - c_table
、c2_table
和 c2_table
也按预期更新。
因此,这里的要点是类型为 1-1-1 的链式结构有效,但类型为 - 1-2-1 的链式结构无效。为什么会这样?有什么方法可以让它发挥作用吗?
经过进一步调查,如果将 child table 链接到两个 parent table 是否有效,我删除了外键 - fk_p_table
, fk2_p_table
.
ALTER TABLE c_table
-> DROP FOREIGN KEY fk_p_table;
ALTER TABLE c2_table
-> DROP FOREIGN KEY fk2_p_table;
另外我 re-add 外键 - fk_c2_table
.
ALTER TABLE cc_table
-> ADD CONSTRAINT fk_c2_table FOREIGN KEY (p_table_id)
-> REFERENCES c2_table (p_table_id)
-> ON DELETE RESTRICT
-> ON UPDATE CASCADE;
c_table
、c2_table
和cc_table
的table结构现在如下:-
SHOW CREATE TABLE c_table;
| c_table | CREATE TABLE `c_table` (
`c_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c_table_id`),
KEY `i_c_table` (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c2_table;
| c2_table | CREATE TABLE `c2_table` (
`c2_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c2_table_id`),
KEY `i_c2_table` (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE cc_table;
| cc_table | CREATE TABLE `cc_table` (
`cc_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`cc_table_id`),
KEY `i_cc_table` (`p_table_id`),
CONSTRAINT `fk_c2_table` FOREIGN KEY (`p_table_id`) REFERENCES `c2_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
所以,现在这基本上是一个1-2连锁阵型。
现在,我尝试更新 table c_table
和 table c2_table
中的值,我成功了 -
UPDATE c_table
-> SET p_table_id = 2 WHERE p_table_id = 1;
UPDATE c2_table
-> SET p_table_id = 4 WHERE p_table_id = 5;
child table cc_table
中的相应值也按预期更新。
所以,要点是 2-1 和 1-2 连锁阵型都有效,但 1-2-1 连锁阵型无效。
为什么 1-2-1 连锁阵型不起作用?有什么方法可以让我完成这项工作吗?
抓得好!
这似乎是 MySQL 8.x 中的错误。我按照您指定的方式尝试了一个包含所有 4 个 FK 的简化示例,并且能够重现该错误。我会向 MySQL 团队提交错误。这没什么大不了的,因为 PKs/FKs 很少改变(尽管他们可以),而且你的例子是一个很大的延伸(尽管它应该有效)。
我在 PostgreSQL 13 中尝试了相同的脚本,它非常有效。见下文。
MySQL 8 个示例 -- 不起作用
create table t (a int primary key not null);
create table u (
a int primary key not null,
constraint fk1 foreign key (a) references t (a) on update cascade
);
create table v (
a int primary key not null,
constraint fk2 foreign key (a) references t (a) on update cascade
);
create table w (
a int,
constraint fk3 foreign key (a) references u (a) on update cascade,
constraint fk4 foreign key (a) references v (a) on update cascade
);
insert into t (a) values (123);
insert into t (a) values (456);
insert into u (a) values (123);
insert into u (a) values (456);
insert into v (a) values (123);
insert into w (a) values (123);
update t set a = 789 where a = 123;
产生错误:
ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (test
.w
, CONSTRAINT fk4
FOREIGN KEY (a
) REFERENCES v
(a
) ON UPDATE CASCADE)
PostgreSQL 13 示例 -- 有效
create table t (a int primary key not null);
create table u (
a int primary key not null,
constraint fk1 foreign key (a) references t (a) on update cascade
);
create table v (
a int primary key not null,
constraint fk2 foreign key (a) references t (a) on update cascade
);
create table w (
a int,
constraint fk3 foreign key (a) references u (a) on update cascade,
constraint fk4 foreign key (a) references v (a) on update cascade
);
insert into t (a) values (123);
insert into t (a) values (456);
insert into u (a) values (123);
insert into u (a) values (456);
insert into v (a) values (123);
insert into w (a) values (123);
update t set a = 789 where a = 123;
所有四个表都按预期更新,如您在 fiddle.
中所见
我创建了 4 个 tables - p_table
、c_table
、c2_table
和 cc_table
。 table结构如下:-
SHOW CREATE TABLE p_table;
| p_table | CREATE TABLE `p_table` (
`p_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c_table;
| c_table | CREATE TABLE `c_table` (
`c_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c_table_id`),
KEY `i_c_table` (`p_table_id`),
CONSTRAINT `fk_p_table` FOREIGN KEY (`p_table_id`) REFERENCES `p_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c2_table;
| c2_table | CREATE TABLE `c2_table` (
`c2_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c2_table_id`),
KEY `i_c2_table` (`p_table_id`),
CONSTRAINT `fk2_p_table` FOREIGN KEY (`p_table_id`) REFERENCES `p_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE cc_table;
| cc_table | CREATE TABLE `cc_table` (
`cc_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`cc_table_id`),
KEY `i_cc_table` (`p_table_id`),
CONSTRAINT `fk_c2_table` FOREIGN KEY (`p_table_id`) REFERENCES `c2_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
此处,table c_table
的第 p_table_id
列和 table c2_table
的第 p_table_id
列引用了 p_table_id
列table p_table
通过外键。
同样,table cc_table
的第 p_table_id
列引用了 table c_table
的第 p_table_id
列和 p_table_id
列table c2_table
通过外键。
所有参考中的参考选项都是-
ON DELETE RESTRICT
ON UPDATE CASCADE
这是某种 1-2-1 连锁结构。
现在,我按如下方式填充 4 tables :-
SELECT * FROM p_table;
+------------+----------+
| p_table_id | value |
+------------+----------+
| 1 | p_value1 |
| 2 | p_value2 |
| 3 | p_value3 |
| 4 | p_value4 |
| 5 | p_value5 |
+------------+----------+
SELECT * FROM c_table;
+------------+------------+-----------+
| c_table_id | p_table_id | value |
+------------+------------+-----------+
| 1 | 1 | c_value11 |
| 2 | 2 | c_value21 |
| 3 | 2 | c_value22 |
| 4 | 3 | c_value31 |
| 5 | 3 | c_value32 |
| 6 | 3 | c_value33 |
| 7 | 4 | c_value41 |
| 8 | 4 | c_value42 |
| 9 | 4 | c_value43 |
| 10 | 4 | c_value44 |
| 11 | 5 | c_value51 |
| 12 | 5 | c_value52 |
| 13 | 5 | c_value53 |
| 14 | 5 | c_value54 |
| 15 | 5 | c_value55 |
+------------+------------+-----------+
SELECT * FROM c2_table;
+-------------+------------+-----------+
| c2_table_id | p_table_id | value |
+-------------+------------+-----------+
| 1 | 1 | c_value11 |
| 2 | 2 | c_value21 |
| 3 | 2 | c_value22 |
| 4 | 3 | c_value31 |
| 5 | 3 | c_value32 |
| 6 | 3 | c_value33 |
| 7 | 4 | c_value41 |
| 8 | 4 | c_value42 |
| 9 | 4 | c_value43 |
| 10 | 4 | c_value44 |
| 11 | 5 | c_value51 |
| 12 | 5 | c_value52 |
| 13 | 5 | c_value53 |
| 14 | 5 | c_value54 |
| 15 | 5 | c_value55 |
+-------------+------------+-----------+
SELECT * FROM cc_table;
+-------------+------------+------------+
| cc_table_id | p_table_id | value |
+-------------+------------+------------+
| 1 | 1 | cc_value11 |
| 2 | 1 | cc_value12 |
| 3 | 1 | cc_value13 |
| 4 | 1 | cc_value14 |
| 5 | 1 | cc_value15 |
| 6 | 2 | cc_value21 |
| 7 | 2 | cc_value22 |
| 8 | 2 | cc_value23 |
| 9 | 2 | cc_value24 |
| 10 | 3 | cc_value31 |
| 11 | 3 | cc_value32 |
| 12 | 3 | cc_value33 |
| 13 | 4 | cc_value41 |
| 14 | 4 | cc_value42 |
| 15 | 5 | cc_value51 |
+-------------+------------+------------+
现在,我尝试更新 table p_table
中的一个值。预期的行为是所有 child table 的相应值将得到更新。
但是,我收到以下错误 -
UPDATE p_table
-> SET p_table_id = 3333 WHERE p_table_id = 3;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`constraints`.`cc_table`, CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE)
现在,我尝试删除链接 cc_table
和 c2_table
的外键 fk_c2_table
。所有 child table 最终都链接到 parent table p_table
.
ALTER TABLE cc_table
-> DROP FOREIGN KEY fk_c2_table;
现在,我尝试更新 table p_table
中的一个值,我成功了。
UPDATE p_table
-> SET p_table_id = 3333 WHERE p_table_id = 3;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0
三个 child table 中的相应值 - c_table
、c2_table
和 c2_table
也按预期更新。
因此,这里的要点是类型为 1-1-1 的链式结构有效,但类型为 - 1-2-1 的链式结构无效。为什么会这样?有什么方法可以让它发挥作用吗?
经过进一步调查,如果将 child table 链接到两个 parent table 是否有效,我删除了外键 - fk_p_table
, fk2_p_table
.
ALTER TABLE c_table
-> DROP FOREIGN KEY fk_p_table;
ALTER TABLE c2_table
-> DROP FOREIGN KEY fk2_p_table;
另外我 re-add 外键 - fk_c2_table
.
ALTER TABLE cc_table
-> ADD CONSTRAINT fk_c2_table FOREIGN KEY (p_table_id)
-> REFERENCES c2_table (p_table_id)
-> ON DELETE RESTRICT
-> ON UPDATE CASCADE;
c_table
、c2_table
和cc_table
的table结构现在如下:-
SHOW CREATE TABLE c_table;
| c_table | CREATE TABLE `c_table` (
`c_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c_table_id`),
KEY `i_c_table` (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=556 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE c2_table;
| c2_table | CREATE TABLE `c2_table` (
`c2_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`c2_table_id`),
KEY `i_c2_table` (`p_table_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
SHOW CREATE TABLE cc_table;
| cc_table | CREATE TABLE `cc_table` (
`cc_table_id` int unsigned NOT NULL AUTO_INCREMENT,
`p_table_id` int unsigned DEFAULT NULL,
`value` varchar(40) DEFAULT NULL,
PRIMARY KEY (`cc_table_id`),
KEY `i_cc_table` (`p_table_id`),
CONSTRAINT `fk_c2_table` FOREIGN KEY (`p_table_id`) REFERENCES `c2_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_c_table` FOREIGN KEY (`p_table_id`) REFERENCES `c_table` (`p_table_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
所以,现在这基本上是一个1-2连锁阵型。
现在,我尝试更新 table c_table
和 table c2_table
中的值,我成功了 -
UPDATE c_table
-> SET p_table_id = 2 WHERE p_table_id = 1;
UPDATE c2_table
-> SET p_table_id = 4 WHERE p_table_id = 5;
child table cc_table
中的相应值也按预期更新。
所以,要点是 2-1 和 1-2 连锁阵型都有效,但 1-2-1 连锁阵型无效。
为什么 1-2-1 连锁阵型不起作用?有什么方法可以让我完成这项工作吗?
抓得好!
这似乎是 MySQL 8.x 中的错误。我按照您指定的方式尝试了一个包含所有 4 个 FK 的简化示例,并且能够重现该错误。我会向 MySQL 团队提交错误。这没什么大不了的,因为 PKs/FKs 很少改变(尽管他们可以),而且你的例子是一个很大的延伸(尽管它应该有效)。
我在 PostgreSQL 13 中尝试了相同的脚本,它非常有效。见下文。
MySQL 8 个示例 -- 不起作用
create table t (a int primary key not null);
create table u (
a int primary key not null,
constraint fk1 foreign key (a) references t (a) on update cascade
);
create table v (
a int primary key not null,
constraint fk2 foreign key (a) references t (a) on update cascade
);
create table w (
a int,
constraint fk3 foreign key (a) references u (a) on update cascade,
constraint fk4 foreign key (a) references v (a) on update cascade
);
insert into t (a) values (123);
insert into t (a) values (456);
insert into u (a) values (123);
insert into u (a) values (456);
insert into v (a) values (123);
insert into w (a) values (123);
update t set a = 789 where a = 123;
产生错误:
ER_NO_REFERENCED_ROW_2: Cannot add or update a child row: a foreign key constraint fails (
test
.w
, CONSTRAINTfk4
FOREIGN KEY (a
) REFERENCESv
(a
) ON UPDATE CASCADE)
PostgreSQL 13 示例 -- 有效
create table t (a int primary key not null);
create table u (
a int primary key not null,
constraint fk1 foreign key (a) references t (a) on update cascade
);
create table v (
a int primary key not null,
constraint fk2 foreign key (a) references t (a) on update cascade
);
create table w (
a int,
constraint fk3 foreign key (a) references u (a) on update cascade,
constraint fk4 foreign key (a) references v (a) on update cascade
);
insert into t (a) values (123);
insert into t (a) values (456);
insert into u (a) values (123);
insert into u (a) values (456);
insert into v (a) values (123);
insert into w (a) values (123);
update t set a = 789 where a = 123;
所有四个表都按预期更新,如您在 fiddle.
中所见