无法调用MySQL触发器

时间:2013-04-03 06:32:30

标签: php mysql mysqli

创建触发器成功

mysqli_query($this->conn,
   "CREATE TRIGGER `before_delete_address`
    BEFORE DELETE ON address FOR EACH ROW
    DELETE FROM city WHERE cityid = OLD.cityid");

但是当我执行以下查询时

DELETE FROM address WHERE addressid = 18

它输出以下错误代码

Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`gamecomp`.`address`, CONSTRAINT `cityid` FOREIGN KEY (`cityid`) REFERENCES `city` (`cityid`) ON UPDATE CASCADE)    0.039 sec

地址表上的约束设置为On Update cascadeOn Delete restrict

地址表的列为addressid, address, cityid, zipcode,cityid是对城市表的FK引用,包含cityid, city, countryid

有人可以指出我做错了什么吗?感谢

2 个答案:

答案 0 :(得分:2)

address FOREIGN KEY (cityid) REFERENCES city (cityid) ON DELETE RESTRICT表示您不能删除任何address.cityid引用的城市。由于这正是您的触发器所做的,因此会出现外键约束错误。

即使您将此触发器设为AFTER DELETE ON,您仍可能有其他引用城市的地址行,这意味着您可能仍会收到外键约束错误。您还应该验证city表上没有触发器可能会扰乱address中外键的约束。

在删除相应的cityid之前,您需要首先验证对city的所有引用都已消失。坦率地说,我不相信你甚至应该尝试这样做。在设计良好的架构中,一些孤立的记录应该不是问题。如果他们真的麻烦你,他们可以定期用cronjob删除,而不是用触发器删除。

如果您坚持使用触发器,请尝试以下操作:

CREATE TRIGGER `delete_city_orphans`
AFTER DELETE ON address FOR EACH ROW
DELETE FROM city WHERE city.id=OLD.cityid
   AND NOT EXISTS (SELECT * FROM address WHERE cityid=OLD.cityid)

答案 1 :(得分:0)

而不是BEFORE DELETE ON城市使用AFTER DELETE ON地址