一个表为空时多删除,未知表错误

时间:2016-05-28 05:36:45

标签: php mysql

我从两个带主要条目的表中删除。

  • 两个表都用于存储图片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;

1 个答案:

答案 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 . "'";

特别注意事项

  1. 表必须使用InnoDB引擎,因为外键不能与MyISAM一起使用。
  2. ALTER TABLE `stat` ENGINE=InnoDB;
    ALTER TABLE `favourites` ENGINE=InnoDB;
    ALTER TABLE `s_images` ENGINE=InnoDB;
    
    1. INSERT和UPDATE必须使用正确的顺序,这意味着当favourites.image = 1的记录不存在时,您无法在s_images.id = 1上创建关联。需要在s_images.id = 1记录之前创建记录favourites

    2. 当引用不存在的id时,您将无法添加FOREIGN KEY约束。您可以使用

    3. 覆盖此行为
      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;
      
      1. 为了防止删除记录,出于历史参考目的,您可以将约束设置为设置NULL而不是级联。
      2.  
        ALTER TABLE `favourites`
            ADD CONSTRAINT `FK_favourites_s_images` FOREIGN KEY (`image`) REFERENCES `s_images` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;