sqlite 如何从VACUUM修复“UNIQUE约束失败”(也是INTEGRITY_PROCESSING失败)

ezykj2lf  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(130)

我使用一个应用程序,它使用这个表创建这个SQLite DB:

CREATE TABLE expense_report (_id INTEGER PRIMARY KEY, ...)

由于某种原因,_id(这是rowid)在该数据库中变得无效。当我扫描表时,我看到最后一行得到了一个_id,这个id很久以前就已经被使用了:
1,2,3.,1137,1138,...,1147,1149,.,12263,122641138,...,1148
我在上面突出显示了一些范围,在这些范围中,我看到我对完全不同的行使用了相同的_id(其余的值根本不匹配)。
查询这个DB通常会得到不准确的结果。例如:

SELECT
    (SELECT MAX(_ID) FROM expense_report) DirectMax
    , (SELECT MAX(_ID) FROM (SELECT _ID FROM expense_report ORDER BY _ID DESC)) RealMax;

| DirectMax | RealMax |
| 1148      | 12264   |

通过DB Browser for SQLite向这个表中插入一个新行也会生成一个1149的_id(而不是12265),所以如果我继续使用这个DB,问题会变得更糟。
运行PRAGMA QUICK_REPORT或PRAGMA INTEGRITY_REPORT会显示以下错误响应:

  • 在主数据库中 *

1598.第1598章孩子:操作系统出错
运行VACUUM也会检测到这个问题,但似乎无法修复它:
执行完成,但有错误。
结果:UNIQUE约束失败:expense_report._id
有人知道如何修复这些重复的ROWID值吗?

83qze16e

83qze16e1#

我最初修复了我的问题,数据库只是恢复到旧的备份数据库。
但今天我发现它又发生了(其他记录),我终于通过DB Browser for SQLite手动版本修复了它。
我有这个查询来检查重复行的ID:

SELECT _id, COUNT(*) c FROM expense_report GROUP BY _id HAVING c > 1;

但是这个特定的查询最初没有返回任何行。这种情况在以下情况发生变化:
1.从expense_report表中删除PK。
1.运行该查询再次检查重复行的ID,现在我得到:

1506    2
 1507    2
 1508    2

1.浏览expense_report并搜索这些键中的每一个,发现它们在金额列中都有不正确的值,并且它们都以2022-12开头。
1.已在数量列中搜索2022-12
1.选择所有的结果(这是只有这3个坏行),并通过DEL键删除它们。
然后在问题中发布的所有查询都正常工作。

相关问题