我有一个名为“estoque”的表,其外键引用另一个名为“produto”的表。然后我用几行填充了两个表。
这是我的表格:
CREATE TABLE `produto` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NOME` varchar(45) NOT NULL,
`PRECO` float NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `NOME_UNIQUE` (`NOME`)
);
CREATE TABLE `estoque` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ID_PRODUTO` int(11) NOT NULL,
`QUANTIDADE_PRODUTO` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `fk_Estoque_Produto1_idx` (`ID_PRODUTO`),
CONSTRAINT `fk_Estoque_Produto1` FOREIGN KEY (`ID_PRODUTO`)
REFERENCES `produto` (`ID`)
);
我需要“estoque”来始终引用“产品”上的所有现有行。所以我在产品上创建了一个 AFTER INSERT 和 AFTER UPDATE 触发器:
CREATE TRIGGER `cadastrar_novo_produto_no_estoque`
AFTER INSERT ON `produto`
FOR EACH ROW
INSERT IGNORE INTO estoque (ID_PRODUTO)
VALUES (NEW.ID);
编辑:实际上,由于我无法更改“produto”上的“ID”列,因为它是主键,所以我认为我根本不需要 AFTER UPDATE 触发器。我说得对吗?
CREATE TRIGGER `atualizar_novo_produto_no_estoque`
AFTER UPDATE ON `produto`
FOR EACH ROW
UPDATE estoque
SET estoque.ID_PRODUTO = NEW.ID
WHERE OLD.estoque.ID_PRODUTO = OLD.ID;
现在我需要一个触发器,这样每次我从“product”中删除一行时,它也会删除“estoque”中的相应行。
我试过这样创建一个:
CREATE TRIGGER `deletar_produto_inexistente_no_estoque`
BEFORE DELETE ON `produto`
FOR EACH ROW DELETE FROM estoque
WHERE estoque.ID_PRODUTO = ID;
但是每当我尝试从“produto”中删除一行时,我都会收到以下错误:
ERROR 1175: 1175: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
SQL Statement:
DELETE FROM `papelaria`.`produto` WHERE (`ID` = '6')
所以我尝试使用 OLD 关键字,如下所示:
CREATE TRIGGER `deletar_produto_inexistente_no_estoque`
BEFORE DELETE ON `produto`
FOR EACH ROW DELETE FROM estoque
WHERE OLD.estoque.ID_PRODUTO = OLD.ID;
然后我得到了这个错误:
ERROR 1054: 1054: Unknown column 'OLD.estoque.ID_PRODUTO' in 'where clause'
SQL Statement:
DELETE FROM `papelaria`.`produto` WHERE (`ID` = '6')
我错过了什么或做错了什么?
P.S.:不确定是否值得一提,但我对 sql 和一般编程还很陌生,所以如果您在回答时考虑到它,我将不胜感激(出于所有目的,假设我不知道关于任何事情的任何事情^^)
提前致谢!
最佳答案
您可以将 FK 修改为:
CONSTRAINT `fk_Estoque_Produto1`
FOREIGN KEY (`ID_PRODUTO`)
REFERENCES `produto` (`ID`)
ON DELETE CASCADE
然后您将不再需要删除前触发器,因为 estoque
表中的记录将被自动删除。
类似地,添加 ON UPDATE CASCADE
将解决您的“更新问题”,以防有人更新记录的 PK。
仍然不确定为什么要在 estoque
表中包含虚拟记录。
关于mysql - 在 MySql 中使用删除前触发器删除具有外键约束的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56535179/