我成功使用以下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。欢迎提出有关限制器的评论。
答案 0 :(得分:1)
这种类型的触发器应该与另一种触发器一起正常工作。问题似乎是SQL不必要地引用了_id
字段。它为每一行选择文字字符串“_id”,并将其与同一文字字符串进行比较。
删除'_id'
周围的引号(DELETE
和子SELECT
中的引号)可以解决问题。