在删除类别之前更新相关帖子

Posted

技术标签:

【中文标题】在删除类别之前更新相关帖子【英文标题】:Update the related posts before deleting the category 【发布时间】:2018-08-20 16:03:36 【问题描述】:

我有 2 个具有 one-to-many 关系的表:

                     posts table
___________________________________________________
| id | title | content | category_id | posts_order |                                        
|____|_______|_________|_____________|_____________|
| 1  | test1 | testing |     1       |       0     |   
| 2  | test2 | testing |     1       |       1     |   
| 3  | test3 | testing |     2       |       2     |   
| .  | ..... | ....... |     .       |       .     |   
|____|_______|_________|_____________|_____________|


       categories table
___________________________
| c_id | c_name | c_order |                                       
|______|________|_________|
|   1  |  cat1  |    0    |      
|   2  |  cat2  |    1    |      
|   3  |  cat3  |    2    |      
| .    | ..... | .......  |      
|______|_______|__________|

他们通过posts.category_idcategories.c_id 加入,删除和更新CASCADE

我正在寻找的是,在删除类别之前,将category_id 更新为100,这是未分类的类别。

我试过了:

global $wpdb;

//Category id to remove.
$remove_id = 2;

//Column to update
$data = array(
    "category_id" => 100
);

$where = array('category_id' => $remove_id);

//Update the posts that has the id 2
$wpdb->update('posts', $data, $where);

//Delete the category
$wpdb->delete( 'categories', array( 'c_id' => $remove_id ) );

但我得到了那个错误:

WordPress database error: [Cannot add or update a child row: a foreign key constraint fails 

(`myposts`.`posts`, CONSTRAINT `posts_categories` FOREIGN KEY (`category_id`) REFERENCES 

`categories` (`c_id`) ON DELETE CASCADE ON UPDATE CASCADE)]
UPDATE `posts` SET `category_id` = '100' WHERE `category_id` = '2'

如何将category_id = 2 的帖子更新为100,在删除c_id = 2 的类别之前?

【问题讨论】:

【参考方案1】:

您遇到此问题是因为ON UPDATE CASCADEForeign Keys 锁定在您的child-table 中。在这种情况下,您的child-tableposts

ON UPDATE CASCADE 的目的是更新posts 中的category_id 字段,如果它在categoriesparent-table)中发生更改。

例如,将categories 表格表单1 上的c_id 更改为001 将更改posts 上的所有category_id 字段以匹配该更改(假设允许此更改的数据类型)。

如果这是您想要保留的功能,那么您需要在 parent-table 而不是 child 上执行 update 语句。

因此,您需要在categories 上执行此update 而不是更新posts,然后它将cascade 降至posts 以获取相关的category_ids


啊,所以看看你对CASCADE 的使用,我认为你想要的不会在当前设计中发生。由于on update cascade,您将无法updatepostscategory_id,如果您尝试将updatecategories 设置c_id = 100 where c_id = 2 然后删除c_id = 100,您将删除所有postscategory_id = 100 也是如此。

如果您想保留 postsdeleted 类别中的 posts,我建议您从表中删除该 on update cascade 约束。

此外,使用category_id 列作为属于deleted 类别的指示是不好的做法。如果您想知道帖子以前的类别是什么?

以这种方式更改id 列通常也很糟糕,因为这意味着它们不能轻易被索引。考虑更改数据库设计以将deleted 类别移动到某种历史记录表中。然后,您可以像往常一样在posts 上搜索记录,并根据需要简单地包含deleted 类别。

【讨论】:

我可以编辑更新部分,因为目前c_id不会改变 所以你建议创建一个新表并将这些帖子移到其中? 您可以将posts 移动到不同的表中,但这可能是不必要的。相反,我会将已删除的category_ids 移动到另一个表中。然后您可以将记录保留在posts 上。要知道帖子的类别是否被删除,您只需检查 category_id 是否在新的 deleted_categories 表中。由于这样做会改变数据库设计,您可能必须更新搜索posts 表的旧查询。您还可以向categories 表中添加一个字段,例如is_deleted 1=yes, 0=no,然后关闭该字段。任何保留 id 的东西。 我在更新和删除时编辑到no action,但我仍然收到同样的错误,应该采取什么措施? 如果您尝试将constraint 设置为no action 并将deleteupdate posts 表设置为相同的错误。这是因为它们遵循与on cascade 选项相同的规则。您想从表中完全删除 constraint。运行这个:SHOW CREATE TABLE mytable; 以查看约束的名称。

以上是关于在删除类别之前更新相关帖子的主要内容,如果未能解决你的问题,请参考以下文章

php 事件日历PRO:从相关的帖子逻辑中删除帖子标签,因此,仅使用事件类别。

Wordpress - 在发布之前从所选类别中排除帖子类型

Wordpress - 与帖子相关的类别列表

如何在没有插件的情况下从特定类别的帖子的 URL 中删除日期?

php 按类别自定义帖子类型的相关帖子

php 相关帖子,随机拉入同一类别,不包括当前帖子。