我从两个带主要条目的表中删除。
两个表都用于存储图片ID。
一个用于显示图像,另一个用于保存在收藏夹中。
当两个表都有条目时,多删除查询工作正常。
可是:
当收藏表为空时,查询对一个表不起作用并显示错误,因为收藏夹是未知表。
您是否有从两个表中删除多个经验的经验(当一个表为空时)?
我尝试了各种各样但错误相同的方法:
$sql = "DELETE FROM stat, s_images, favourites USING stat, s_images,
favourites WHERE favourites.image=stat.id AND stat.id=s_images.id AND
stat.id=" . $this->id;
$sql = "DELETE stat, s_images,favourites FROM stat, s_images,
favourites WHERE favourites.image=stat.id AND stat.id=s_images.id AND
stat.id=" . $this->id;
答案 0 :(得分:1)
尝试使用显式内连接
DELETE stat, s_images, favourites
FROM stat
INNER JOIN s_images
ON s_images.id = stat.id
INNER JOIN favourites
ON favourites.image = stat.id
WHERE stat.id = $this->id;
如果在任何联接中找不到匹配项,则不会删除任何内容。
示例:http://sqlfiddle.com/#!9/580be/2
否则,您可能需要执行单个查询或在删除时使用Foreign Key Constraints Cascade。
你也可以忽略错误,但这是不好的做法。
DELETE IGNORE stat, s_images, favourites
FROM stat
LEFT JOIN s_images
ON s_images.id = stat.id
LEFT JOIN favourites
ON favourites.image = stat.id
WHERE stat.id = $this->id;
使用外键更新
为s_images.id
+ stat.id
ALTER TABLE `stat`
ADD CONSTRAINT `FK_stat_s_images` FOREIGN KEY (`id`) REFERENCES `s_images` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
为s_images.id
+ favourites.image
ALTER TABLE `favourites`
ADD CONSTRAINT `FK_favourites_s_images` FOREIGN KEY (`image`) REFERENCES `s_images` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
然后您需要做的就是执行查询以删除图像,MySQL将确保您的记录得到适当管理,并有助于优化。
$sql = "DELETE FROM s_images
WHERE s_images.id = '" . $this->id . "'";
特别注意事项
ALTER TABLE `stat` ENGINE=InnoDB;
ALTER TABLE `favourites` ENGINE=InnoDB;
ALTER TABLE `s_images` ENGINE=InnoDB;
INSERT和UPDATE必须使用正确的顺序,这意味着当favourites.image = 1
的记录不存在时,您无法在s_images.id = 1
上创建关联。需要在s_images.id = 1
记录之前创建记录favourites
。
当引用不存在的id时,您将无法添加FOREIGN KEY约束。您可以使用
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `stat`
ADD CONSTRAINT `FK_stat_s_images` FOREIGN KEY (`id`) REFERENCES `s_images` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
ALTER TABLE `favourites`
ADD CONSTRAINT `FK_favourites_s_images` FOREIGN KEY (`image`) REFERENCES `s_images` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;