Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于删除旧结果的SQL触发器_Sql_Sqlite - Fatal编程技术网

用于删除旧结果的SQL触发器

用于删除旧结果的SQL触发器,sql,sqlite,Sql,Sqlite,我们有一个数据库,用于存储嵌入式设备的测试结果。有一个表,其中列用于不同类型的故障(详细信息不相关),还有一个主键“keynum”和一个列出故障数的“NUM_failures”列。我们存储过程和失败,因此过程的“NUM_failures”中有一个“0” 为了防止数据库无限制地增长,我们希望保留最后1000个结果,加上最后50个超出1000个的失败。所以,在最坏的情况下,表中可能有1050个条目。我试图找到最有效的SQL插入触发器来删除额外的条目。我会给出我目前为止的答案,但我想看看是否有人能想出

我们有一个数据库,用于存储嵌入式设备的测试结果。有一个表,其中列用于不同类型的故障(详细信息不相关),还有一个主键“keynum”和一个列出故障数的“NUM_failures”列。我们存储过程和失败,因此过程的“NUM_failures”中有一个“0”

为了防止数据库无限制地增长,我们希望保留最后1000个结果,加上最后50个超出1000个的失败。所以,在最坏的情况下,表中可能有1050个条目。我试图找到最有效的SQL插入触发器来删除额外的条目。我会给出我目前为止的答案,但我想看看是否有人能想出更好的方法,因为SQL不是我经常做的事情

如果相关的话,我们在非Windows平台上使用SQLITE3


编辑:为了澄清,我遇到问题的部分是删除,特别是与最近50次失败相关的部分。

您要删除这些条目的原因是为了使数据库变得太大,而不是使其处于某种特殊状态。为此,我不会使用触发器,而是设置一个作业,以便在某个时间间隔内运行以清理表。

要删除这些条目的原因是为了保持数据库增长过大,而不是使其处于某种特殊状态。为此,我真的不使用触发器,而是设置一个作业以在某个时间间隔运行来清理表。

到目前为止,我已经使用了一个结合了触发器的视图,但我不确定它是否会因其他原因而起作用

CREATE VIEW tablename_view AS SELECT keynum FROM tablename WHERE NUM_FAILURES!='0' 
    ORDER BY keynum DESC LIMIT 50;
CREATE TRIGGER tablename_trig
  AFTER INSERT ON tablename WHEN (((SELECT COUNT(*) FROM tablename) >= 1000) or
    ((SELECT COUNT(NUM_FAILURES) FROM tablename WHERE NUM_FAILURES!='0') >= 50))
  BEGIN
     DELETE FROM tablename WHERE ((((SELECT MAX(keynum) FROM ibit) - keynum) >= 1000)
  AND 
     ((NUM_FAILURES=='0') OR ((SELECT MIN(keynum) FROM tablename_view) > keynum)));
  END;

到目前为止,我已经使用了一个结合了触发器的视图,但我不确定它是否会因为其他原因而起作用

CREATE VIEW tablename_view AS SELECT keynum FROM tablename WHERE NUM_FAILURES!='0' 
    ORDER BY keynum DESC LIMIT 50;
CREATE TRIGGER tablename_trig
  AFTER INSERT ON tablename WHEN (((SELECT COUNT(*) FROM tablename) >= 1000) or
    ((SELECT COUNT(NUM_FAILURES) FROM tablename WHERE NUM_FAILURES!='0') >= 50))
  BEGIN
     DELETE FROM tablename WHERE ((((SELECT MAX(keynum) FROM ibit) - keynum) >= 1000)
  AND 
     ((NUM_FAILURES=='0') OR ((SELECT MIN(keynum) FROM tablename_view) > keynum)));
  END;

我认为您可能使用了错误的数据结构。相反,我将创建两个表,并预先填充其中一个1000行(成功),另一个50行(失败)。在每个服务器上放置一个主ID。当您记录一个结果而不是插入新行时,请为输入的最后一个时间戳记录查找ID+1值(在表中循环回0 if>max(ID)),并使用新值更新它

这样做的优点是预先分配存储空间,不需要触发器,并且内部逻辑一致。您还可以非常简单地通过预先填充更多记录来调整日志的大小,而无需更改程序逻辑


您可以在这方面使用多种变体,但使用闭环结构而不是开放列表的想法似乎更符合问题域。

我认为您可能使用了错误的数据结构。相反,我将创建两个表,并预先填充其中一个1000行(成功),另一个50行(失败)。在每个服务器上放置一个主ID。当您记录一个结果而不是插入新行时,请为输入的最后一个时间戳记录查找ID+1值(在表中循环回0 if>max(ID)),并使用新值更新它

这样做的优点是预先分配存储空间,不需要触发器,并且内部逻辑一致。您还可以非常简单地通过预先填充更多记录来调整日志的大小,而无需更改程序逻辑

您可以在这方面使用多种变体,但使用闭环结构而不是开放列表的想法似乎更符合问题域。

这是怎么回事:

DELETE  
FROM  table 
WHERE ( id   > ( SELECT max(id) - 1000 FROM table ) 
        AND  num_failures   = 0 
      )
OR    id     > ( SELECT max(id) - 1050 FROM table ) 
如果性能是一个问题,那么最好定期删除,而不是每次插入

这个怎么样:

DELETE  
FROM  table 
WHERE ( id   > ( SELECT max(id) - 1000 FROM table ) 
        AND  num_failures   = 0 
      )
OR    id     > ( SELECT max(id) - 1050 FROM table ) 

如果性能是一个问题,那么最好定期删除,而不是每次插入

一般来说,这是正确的,但问题是指定了一个嵌入式设备,因此我们不能假设有任何机制可以实现这一点,或者假设它是可取的。Cruachan对该平台的看法是正确的。而且,触发器本身并不是真正的问题;这是它的删除部分,我有麻烦。即使我是作为一个单独线程的一部分做的,这也是一样的。一般来说,这是正确的,但问题指定了一个嵌入式设备,所以我们不能假设有任何机制可以做到这一点,或者如果有,这将是可取的。Cruachan对这个平台的看法是正确的。而且,触发器本身并不是真正的问题;这是它的删除部分,我有麻烦。即使我是作为一个单独线程的一部分来做的,这也是一样的。这对我来说不起作用有几个原因。首先,我们并没有在任何时候都在系统中有一个准确的时间和日期戳。此外,我需要失败和失败之间保持正确的关系。这对我来说不起作用有几个原因。首先,我们并没有在任何时候都在系统中有一个准确的时间和日期戳。此外,我需要失败和通过之间的正确关系。这并不是我想要的,因为如果1000次失败中有50次失败,你不需要保持更多的失败。然而,标准可能根本不需要那么复杂。这并不是我想要的,因为如果你在1000次失败中有50次失败,你不需要让更多的失败过去。然而,标准可能根本不需要那么复杂。