简体   繁体   English

尽管外键中有ON UPDATE CASCADE,MySQL仍不允许更新

[英]MySQL won't allow update despite ON UPDATE CASCADE in foreign key

I have a really weird problem with MySQL where ON UPDATE CASCADE is behaving like ON UPDATE RESTRICT. 我对MySQL有一个非常奇怪的问题,其中ON UPDATE CASCADE的行为类似于ON UPDATE RESTRICT。

I have two MySQL servers, an old Windows Server 2012 and a new Ubuntu 16.04 LTS. 我有两个MySQL服务器,一个旧的Windows Server 2012和一个新的Ubuntu 16.04 LTS。

On both servers, I have three tables -- item, invoice and invoice_box 在两台服务器上,我都有三个表-项目,发票和invoice_box

CREATE TABLE `item`  (
  `id` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `idInvoice` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `boxNumber` tinyint(4) NULL DEFAULT NULL,

  CONSTRAINT `fk_gauge_item_invoice` FOREIGN KEY (`idInvoice`) REFERENCES `invoice` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `fk_gauge_item_invoice_box` FOREIGN KEY (`idInvoice`, `boxNumber`) REFERENCES `invoice_box` (`idInvoice`, `boxNumber`) ON DELETE SET NULL ON UPDATE CASCADE
)

CREATE TABLE `invoice_box`  (
 `idInvoice` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
 `boxNumber` tinyint(4) NOT NULL,

  CONSTRAINT `fk_gauge_box_invoice` FOREIGN KEY (`idInvoice`) REFERENCES `invoice` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
)

CREATE TABLE `invoice`  (
 `id` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
)

On my old Windows server, if I update the invoice id, the update cascades to the item and invoice_box table successfully. 在旧的Windows服务器上,如果我更新发票ID,则更新成功地级联到item和invoice_box表。

On the Ubuntu server, it works only if 在Ubuntu服务器上,仅当

  1. If there are no entries in item table, then it cascades to invoice_box table correctly. 如果item表中没有条目,那么它将正确地级联到invoice_box表。
  2. If there are no entries in invoice_box table, then it cascades to item table correctly. 如果invoice_box表中没有任何条目,则它将正确地级联到item表。
  3. If there are entries in both item and invoice_box table, then it fails with the following message. 如果iteminvoice_box表中都有item ,则失败并显示以下消息。

    1452 - Cannot add or update a child row; 1452-无法添加或更新子行; a foreign key constraint fails (product.item CONSTRAINT fk_item_invoice FOREIGN KEY (idInvoice) REFERENCES invoice(id) ON DELETE SET NULL ON UPDATE CASCADE) 外键约束失败(product.item CONSTRAINT fk_item_invoice FOREIGN KEY(idInvoice)参考发票(id)ON在更新级联时删除集为空)

I don't understand why this won't work exactly the same on both servers. 我不明白为什么这在两台服务器上无法完全相同。 I did a dump from the Windows server to migrate onto the Ubuntu server, if that makes any difference. 我从Windows服务器进行了转储,以迁移到Ubuntu服务器,如果有什么不同的话。

Code works as coded with the removal of fk_gauge_item_invoice 代码与删除fk_gauge_item_invoice代码fk_gauge_item_invoice

drop table if exists i;
drop table if exists ib;
drop table if exists inv;
CREATE TABLE `inv`  (
 `id` varchar(11)  CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
 primary key (id)
);

CREATE TABLE `ib`  (
 `idInvoice` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
 `boxNumber` tinyint(4) NOT NULL,
  key ib1(idinvoice,boxnumber),
  CONSTRAINT `fk_gauge_box_invoice` FOREIGN KEY (`idInvoice`) REFERENCES `inv` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE TABLE `i`  (
  `id` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `idInvoice` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `boxNumber` tinyint(4) NULL DEFAULT NULL,

  #CONSTRAINT `fk_gauge_item_invoice` FOREIGN KEY (`idInvoice`) REFERENCES `inv` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `fk_gauge_item_invoice_box` FOREIGN KEY (`idInvoice`, `boxNumber`) REFERENCES `ib` (`idInvoice`, `boxNumber`) ON DELETE SET NULL ON UPDATE CASCADE
);

insert into inv values (1),(2),(3);
insert into ib values (1,1),(1,2),(2,1),(2,2),(2,3);
insert into i values (1,1,1),(1,1,2),(2,1,1),(2,2,2),(2,2,3);

MariaDB [sandbox]> update inv set id = 10 where id = 1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> select * from inv;
+----+
| id |
+----+
| 10 |
| 2  |
| 3  |
+----+
3 rows in set (0.00 sec)

MariaDB [sandbox]> select * from ib;
+-----------+-----------+
| idInvoice | boxNumber |
+-----------+-----------+
| 10        |         1 |
| 10        |         2 |
| 2         |         1 |
| 2         |         2 |
| 2         |         3 |
+-----------+-----------+
5 rows in set (0.00 sec)

MariaDB [sandbox]> select * from i;
+----+-----------+-----------+
| id | idInvoice | boxNumber |
+----+-----------+-----------+
| 1  | 10        |         1 |
| 1  | 10        |         2 |
| 2  | 10        |         1 |
| 2  | 2         |         2 |
| 2  | 2         |         3 |
+----+-----------+-----------+
5 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> update ib set idinvoice = 20 where idinvoice = 10;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`sandbox`.`ib`, CONSTRAINT `fk_gauge_box_invoice` FOREIGN KEY (`idInvoice`) REFERENCES `inv` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

So I'm not clear what your problem is - if you can set up a sql fiddle to demonstrate your issue then that would help. 因此,我不清楚您的问题是什么-如果您可以设置一个SQL提琴来演示您的问题,那么这将有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM