使用孤立的 parent id 从 table 中删除嵌套行

Delete nested rows from table with orphaned parent id

我有一个 table,其中 parentId 列对于顶级项目可以是 0,对于属于其他项目的项目可以是数字。嵌套的深度没有限制。

id     parentId     title
-------------------------
1      0            Item1
2      1            Item11
3      2            Item22
4      0            Item2
5      4            Item21

我想要的是每删除一个item,一个child的每个child和child都被删除,直到没有item有一个parentId一个不存在的项目。

我知道我可以循环遍历记录并从底部开始查询 DELETE child 但我想知道这是否只能通过 SQLite 命令完成

此代码将删除 id 列或 parentId 列中具有此“ID”的每一行:

void deleteItemAndChildren(String ID){
        //Deletes the row that has that ID in id column
        int deletedIdsCount = db.delete(tableName, "id=?", new String[]{ID});

        //Deletes the row that has that ID in parentId column
        int deletedChildrenCount = db.delete(tableName, "parentId=?", new String[]{ID});

        Log.i("CountOfDeletedRows", "was "+ ID +" Deleted: " + (deletedIdsCount>0) + " Count of children deleted: " + deletedChildrenCount );
}

干杯!

您可以重新定义 table:

CREATE TABLE tablename (
  `id` INTEGER PRIMARY KEY,
  `parentId` INTEGER,
  `title` VARCHAR(6),
  FOREIGN KEY (`parentId`) REFERENCES tablename(`id`) ON DELETE CASCADE
);

以便列 parentId 是引用列 id 的外键,它必须是 table 的 PRIMARY KEY 或者必须有一个 UNIQUE index/constraint.

ON DELETE CASCADE 操作确保当您删除一行时,所有子行也将被删除(还有子行的子行等)。

此外,您必须将顶级项目设置为 null 而不是 0,这样就不会违反外键约束。

您必须打开打开外键支持,因为它默认是关闭,这可以在SQLiteOpenHelper中完成' s onConfigure() 方法:

@Override
public void onConfigure(SQLiteDatabase db){
    db.setForeignKeyConstraintsEnabled(true);
}

现在,当您从 table 中删除一行时,您删除的行级别以下级别的所有行也将被删除。

您可能必须从设备上卸载该应用程序,以便删除数据库并重新运行以使用新定义重新创建数据库和 table。

看到一个demo