如何解决如何在SQLite中使用触发器为特定表设置最大项目数?
- 您已省略了该
BEFORE | AFTER
子句,因此BEFORE
默认情况下为该子句。这意味着您是 在插入 之前( 而不是插入之后)对行进行计数。 - 这取决于。首先,当表尚未达到限制时,快速计数查找可以为您节省一些时间,因为您可以避免更复杂的删除。但是,一旦表已满,无论如何都必须删除,因此计数只是要做的其他工作。
这应该工作:
private const val MAX_ITEMS = 3
private val TIMESTAMP_FIELD = "timestamp"
private val DELETE_FROM_CALL_LOG_TILL_TRIGGER =
String.format(
"CREATE TRIGGER %1\$s AFTER INSERT ON %2\$s
FOR EACH ROW
BEGIN
DELETE FROM %2\$s WHERE _id =
(SELECT _id FROM %2\$s ORDER BY %4\$s DESC LIMIT 1 OFFSET %3\$s);
END;"
, "delete_till_reached_max", TABLE_NAME, MAX_ITEMS, TIMESTAMP_FIELD)
一旦表中有400行,您就可以像这样调用触发器trg_keep_rowcount_constant
并将其GROUP BY null HAVING
COUNT(*) > %3\$s
从代码中删除。
演示:https://dbfiddle.uk/?rdbms = sqlite_3.27&fiddle = ea3867e20e85927a2de047908771f4f1
解决方法
这是一个简单的问题。
背景
我应该基于时间戳字段在某个表中最多包含400行,因此旧的行将被自动删除。对于这里,我们假设它是3。
该表具有多个字段,但是时间戳在这里很重要。
问题
即使我成功了,由于某种原因,它也使我最大程度地增加了其他项目,因此我只是对其进行了相应的调整。这意味着我得到了3个项目,而不是3个。
private const val MAX_ITEMS = 3
private val TIMESTAMP_FIELD = "timestamp"
private val DELETE_FROM_CALL_LOG_TILL_TRIGGER =
String.format(
"CREATE TRIGGER %1\$s INSERT ON %2\$s
WHEN (select count(*) from %2\$s)>%3\$s
BEGIN
DELETE FROM %2\$s WHERE %2\$s._id IN " +
"(SELECT %2\$s._id FROM %2\$s ORDER BY %2\$s.$TIMESTAMP_FIELD DESC LIMIT %3\$d,-1);
END;","delete_till_reached_max",TABLE_NAME,MAX_ITEMS - 1)
我尝试过的
我试过了 :
- 将条件更改为仅插入(表示没有
WHEN
零件) - 更改
LIMIT %3\$d,-1
为LIMIT -1 OFFSET %3\$d
。还尝试了一个不同于“ -1”的数字(尝试0,因为我认为这是多余的)。
问题
- 为什么我不得不使用
MAX_ITEMS - 1
而不是仅仅使用MAX_ITEMS
?为什么我只剩下4个项目而不是3个项目? - 我在
WHEN
那里有关系吗?好点吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。