SQLite:如何根据时间戳限制行数?

时间:2012-08-05 18:09:27

标签: android sql sqlite triggers database-trigger

我成功使用以下BEFORE INSERT触发器来限制存储在SQLite数据库表位置中的行数。数据库表充当Android应用程序中的缓存。

CREATE TRIGGER 'trigger_locations_insert'
BEFORE INSERT ON 'locations'
WHEN ( SELECT count(*) FROM  'locations' ) > '100'
  BEGIN
    DELETE FROM 'locations' WHERE '_id' NOT IN
    (
      SELECT '_id' FROM 'locations' ORDER BY 'modified_at' DESC LIMIT '100' 
    );
  END

与此同时,我添加了第二个触发器,允许我INSERT OR UPDATE行。 - 关于该主题的讨论可以在another thread中找到。第二个触发器需要VIEW,每个INSERT都会被执行。

CREATE VIEW 'locations_view' AS SELECT * FROM 'locations';

由于INSERT 位置上不再执行TABLE,但VIEW locations_view 上执行VIEW,上述触发器会执行不再工作了。如果我在Failure 1 (cannot create BEFORE trigger on view: main.locations_view) 上应用触发器,则会抛出以下错误消息。

INSERT

问题:

如何更改上述触发器以观察VIEW上的每个INSERT - 或者您是否建议使用其他方法来限制行数?我更愿意在数据库中处理这种操作,而不是在我的客户端上运行前端代码。


效果问题:

虽然限制器(上面的触发器)通常起作用 - 它的性能不是最优的!实际上,数据库操作需要很长时间才能引发ANR。据我所知,原因是限制器在INSERT发生时被称为时间。要优化设置,批量INSERT应该包含在事务中,限制器应该在之后执行。这可能吗?如果您想提供帮助,请将有关批量{{1}}的优化评论放入original question。欢迎提出有关限制器的评论。

1 个答案:

答案 0 :(得分:1)

这种类型的触发器应该与另一种触发器一起正常工作。问题似乎是SQL不必要地引用了_id字段。它为每一行选择文字字符串“_id”,并将其与同一文字字符串进行比较。

删除'_id'周围的引号(DELETE和子SELECT中的引号)可以解决问题。