首页 > 解决方案 > 消除places.sqlite中的重复文件夹

问题描述

由于同步过程出错,我的书签中有几个重复的文件夹。如果您不熟悉,Firefox 会将其书签存储在您的硬盘上的一个名为 places.sqlite 的文件中。您可以通过sqlite 浏览器等工具轻松访问此数据库。正如您在schema中看到的那样,moz_bookmarks 表捕获了书签文件夹和属于它们的书签的分层树结构,如下所示:

在上面的示例中,我不想要两个 Cycling 文件夹。我想将两个 Cycling 文件夹的所有后代合并到一个 Cycling 文件夹下,然后删除空的,所以我最终只有一个 Cycling 文件夹,但没有丢失任何内容。

作为第一步,这里是一个查询,它将找到一个 Cycling 文件夹的所有后代: with cte as ( select id, type, parent, title from moz_bookmarks where id = 2757 --id for one of the Cycling folders union all select b.id, b.type, b.parent, b.title from moz_bookmarks b join cte sub on sub.id = b.parent ) select * from cte;

我需要为这两个文件夹找到后代并合并它们。实际上,Cycling 并不是我唯一的一组重复文件夹。我有几十个,所以我需要能够以类似方式处理它们的代码。

标签: sqlsqlitemozilla

解决方案


您评论中的 CTE 已接近,但您没有保存锚点。要回答您关于游标的问题,不,绝不!每当您考虑使用游标时,您几乎肯定是错的。(好吧,有些场合,但它们确实是出于特殊目的,而不是简单的数据库更新)。

我仍然不清楚数据和你想要做什么,但是这个版本的 CTE 会找到所有没有父级(父级为空)的行,然后是它的所有子级。它还将顶级 id 保存为锚点,以便您可以使用它来滚动其他的。

我敢肯定这不是你需要的 100%,但它应该给你一个可以使用的好主意。

然后,您可以将其保存到临时表中,并将其用作您需要做的任何事情的基础 - 将任何行的父级设置为顶级父级,设置最小创建日期或最大修改日期,或完全删除行。

做这一切都是基于设置而不是尝试使用游标遍历任何内容。

这将是您的带有锚点的 CTE(已保存 topID):

with cte as ( 
    -- Find all the rows that are top level
    select id as TopID, type, id, null as parent, title, 
        datetime(dateAdded/1000000,'unixepoch') as dateAdded, 
        datetime(lastModified/1000000,'unixepoch') as lastModified 
    from moz_bookmarks 
    where parent is null  
union all 
    select cte.TopID, b.type, b.id, b.parent, b.title, 
        datetime(b.dateAdded/1000000,'unixepoch') as dateAdded, 
        datetime(b.lastModified/1000000,'unixepoch') as lastModified 
    from moz_bookmarks b 
    join cte sub on sub.id = b.parent
) 
select * from cte;

推荐阅读