从一个MySQL表中删除父项和所有子项

时间:2015-07-27 19:32:00

标签: php mysql laravel laravel-5 eloquent

我有一个简单的类别表,有一个级别的嵌套。

+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(11)          | NO   | PRI | NULL                | auto_increment |
| name       | varchar(200)     | NO   |     | NULL                |                |
| parent_id  | int(11)          | YES  | MUL | 0                   |                |
| created_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| deleted_at | timestamp        | YES  |     | NULL                |                |
+------------+------------------+------+-----+---------------------+----------------+

我想准备eloqient查询,它将按ID删除类别。如果提供了子类别 - 将其删除。但是如果提供了根类别,请将其与所有孩子一起删除。

我有这样的事情:

\DB::table('categories AS c1')->whereIn('c1.id', function ($query) use ($id) {
        $query->select('c2.id')
            ->from('categories AS c2')
            ->whereNull('c2.deleted_at')
            ->where('c2.parent_id', $id);
    })
    ->orWhere('c1.id', $id)
    ->delete();

但我无法让它发挥作用。我收到了以下错误:

1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'as `c1` where `c1`.`id` in 
(select `c2`.`id` from `categories` as `c2` where `c2' at line 1 (SQL: delete from
`categories` as `c1` where `c1`.`id` in (select `c2`.`id` from `categories` as `c2` where
`c2`.`deleted_at` is null and `c2`.`parent_id` = 15) or `c1`.`id` = 15)

如何改进查询以使其正常工作?

1 个答案:

答案 0 :(得分:1)

如果您要删除 ID等于$ id parent_id等于$ id 的项目,理论上可以使用以下内容:

DB::table('categories')->where('id', $id)->orWhere('parent_id', $id)->delete();

在现实生活中,您可能在 parent_id 字段上设置了外键约束,只要存在子项,就会阻止删除父类别。如果是这种情况,您有两个选择:

  1. 运行2个查询:

    DB :: table('categories') - > where('parent_id',$ id) - > delete(); DB :: table('categories') - > where('id',$ id) - > delete();

  2. 定义约束时,将 ON DELETE 行为设置为 CASCADE 。这样,当删除父项时,其所有子项也将被删除。定义外键约束时,可以在迁移文件中执行此操作

    Schema::table('categories', function (Blueprint $table) {
      $table->foreign('parent_id')->references('id')->on('users')->onDelete('cascade');
    });