【发布时间】:2015-04-24 20:24:27
【问题描述】:
是否可以从关联表中删除(多对多)并在同一事务中插入同一行?
这是我的关联表:
CREATE TABLE image_tag (
imageid bigint(19) NOT NULL,
tagid bigint(19) NOT NULL,
PRIMARY KEY (imageid, tagid));
ALTER TABLE image_tag ADD INDEX FKimage_tag587679 (tagid), ADD CONSTRAINT FKimage_tag587679 FOREIGN KEY (tagid) REFERENCES tag (id);
ALTER TABLE image_tag ADD INDEX FKimage_tag426448 (imageid), ADD CONSTRAINT FKimage_tag426448 FOREIGN KEY (imageid) REFERENCES image (id);
当我在一个事务中创建新图像并插入图像时,插入标签并插入 image_tag,一切正常。
当我想更新Image和I时出现问题:
- 开始交易
- 使用给定的 $id 更新图像
- 调用:DELETE FROM image_tag WHERE imageid = $id
- 检查 image_tag 对于 imageid = $id 是否为空(并且是)
- 检索新标签的 ID(其中一些保持不变)
- 尝试插入 image_tag ...但我收到异常
例外:
Cannot add or update a child row: a foreign key constraint fails (`mydatabase`.`image_tag`, CONSTRAINT `FKimage_tag426448` FOREIGN KEY (`imageid`) REFERENCES `image` (`id`))
数据:
Original data: (194, 123), (194, 225), (194, 291)
New data: (194, 123), (194, 225), (194, 65)
源代码(PHP):
if ($editation) {
if ($values->image->isOk()) {
$url = $img->load($values->id)->getUrl();
$values->image->move($this->wwwDir . "/" . $url);
} else {
$url = null;
}
$img->update($values->name, $values->descr, $url, null, $featured);
} else {
$uname = $img->createUniqueName($values->name);
$url = ImageManager::PATH . "/" . $uname . ".svg";
$values->image->move($this->wwwDir . "/" . $url);
$img->create($userId, $values->name, $url, $values->descr, null, $featured);
}
// Delete old image-tag associations if any
$this->db->query('DELETE FROM image_tag WHERE imageid = %i', $img->getId());
// Save tags and assign them to image
$tagIds = $this->tagManager->saveTags($values->tags);
$assoc = (new Dao\ImageTag())->setDb($this->db);
//throw new \Exception(implode(",", $tagIds));
foreach ($tagIds as $tagId) {
// EXCEPTION IS THROWED HERE (but only after editation)
$assoc->create($img->getId(), $tagId);
}
【问题讨论】:
-
您能否再展示一些示例数据并解释一下为什么需要删除?从您的原始数据到新数据,看起来唯一变化的行是最后一行,我不确定您为什么不能只运行
update查询? -
因为我不想提供额外的逻辑——我应该保留哪些标签,哪些不应该保留——我只是简单地删除所有标签,然后添加所有当前标签,不管哪些是相同的,哪些不是。您认为这种方法不好吗?
-
嗯,这当然很危险,除非你把它全部包装在一个事务中。如果删除有效但插入失败会发生什么?您可能会丢失大量数据。另外,我不确定您是否可以在同一个查询中运行删除和插入。您是否已经坚决反对更新?如果可能的话,我认为这可能是一种更好的方法。
标签: php mysql transactions many-to-many model-associations