2017-01-23 66 views
0

我创建了一个数据库文件,该文件每分钟更新一次读数并存储在SQL Server CE数据库文件中。但是,随着数据库变得非常大,它开始变得非常慢。SQL Server CE&C#删除记录后无法读取表中的数据

我决定在数据库达到一定大小后删除最早的文件,因为它们对我来说没用。我成功地做到这一点使用下面的命令:

command.Append("DELETE FROM MyTable WHERE ID IN (SELECT TOP(" + difference.ToString() + ") ID From MyTable)"); 

其中difference.ToString()是我用来计算我是多么想删除值。

这工作成功,因为我可以使用CompactView打开文件,我也可以键入CompactView中的命令以获得相同的结果。

现在我的问题开始时,我试图读取数据并将其更新到图形上。所以,我的另一种形式的代码执行以下操作:

private void updateGraphTimer_Tick(object sender, EventArgs e) 
{ 
    using (SqlCeConnection connection = new SqlCeConnection(connectionString)) 
    { 
     connection.Open(); 

     using (SqlCeDataAdapter adapter = new SqlCeDataAdapter("SELECT * FROM MyTable", connection)) 
     { 
      // some code that is not relevant between these two statements 
      using (DataTable table = new DataTable()) 
      { 
       StringBuilder command = new StringBuilder(); 
       command.Clear(); 
       command.Append("SELECT TOP(1) ID FROM MyTable ORDER BY ID DESC"); 

       using (SqlCeCommand com = new SqlCeCommand(command.ToString(), connection)) 
       { 
        int value = (int)com.ExecuteScalar(); 
        graphPage.latestID = value; 

        if (value > graphPage.startID) 
        { 
         DataColumn xDateColumn; 
         xDateColumn = new DataColumn("XDate"); 
         xDateColumn.DataType = typeof(double); 
         table.Columns.Add(xDateColumn); 

         adapter.Fill(graphPage.startID, value, table); 

我的问题是,该表是空的,即使从(int)com.ExecuteScalar()值返回一个值!如果我没有执行删除,它一切正常!

我无法弄清楚发生了什么!我能想到的唯一事情就是阅读和编写sql文件。

非常感谢!

+0

你说你运行删除表时显示空了吗? – Moudiz

+0

如何以及何时运行删除?它是一个批处理手动过程,还是由另一个线程自动运行?看起来可能存在同步问题 – salvolds

+0

在单独的窗体上有两个定时器,一个定时器用于使用最新数据填充数据库并且它一直运行。另一个定时器在图形程序启动时使用。他们每分钟更新数据或更快。当数据库变大时,最早的数据被删除。同时,图形程序试图通过读取相同的数据库来更新读数来显示。尽管获得最新的ID字段能够正常工作并给出正确的读数,但是当我填写表格时,它什么也没有显示。干杯 – aaz

回答

0

最好不要在这里使用TOP。随着ID自动增加,获取最高ID,然后在该ID之前最大删除,因为图形部分使用了最新的ID。例如,删除当前最大ID或低于最大ID - 10左右的所有内容。

DELETE * from table where ID < MAX(ID);

如果在删除时使用TOP,则删除所有值,包括TOP(最后一个ID)。在图形部分,您也正在访问最后一个ID。

+0

谢谢但删除工作,它删除最旧的记录,而不是最新的记录。例如,我删除了400条记录中的100条记录。因此,实际的语句有效,因为ExecuteScalar返回了正确的ID,但没有显示数据。 – aaz

+0

我发现了另一个问题!这可能与你所说的有关。当我做一个删除时,它会插入记录,它将新数据插入数据库的顶部而不是底部! – aaz

0

所以,你有两个问题:

  1. 你的表是空删除
  2. 查询返回尽管事实的结果,该表是空的

关于第一个后一个问题是在你的删除语句中:由于某种原因,你的difference值高于或等于你表中的行数,并且会删除整个表。 我会看你计算它的方式。 在任何情况下,如果你对你的表的insert_date我会改变delete语句像这样从今天删除行早于10天:

DELETE FROM MyTable WHERE ID IN (SELECT ID From MyTable where insert_date < DATEADD(day, -10, GETDATE()) 

第二个问题是关系到一个事实,即并发问题的两种线程正在工作:它可能发生在数据被删除之前读取数据(并且数据可用);所以如果这是一个印象,你还没有真正从空白表获得查询结果。

+0

谢谢,差异值不高于表中的行数,我已经遍历代码,我甚至退出了​​软件,使用CompactView查看数据库来查看数据,并确实删除了正确的数量,它似乎没有显示在桌子上的数据,但确实识别正确的ID。 – aaz

+0

@aaz:这只是你在紧凑视图上运行的select语句上的一个问题吗? – salvolds

0

我想我想出了问题!原谅我,如果你试图向我解释这一点,我没有得到它,但在这里!问题是填充表时,而从ExecuteScalar返回的值是正确的,该ID大于表,因为表从0计算而不是减去的数量!

因此,例如我从5000删除1000条记录,最旧的记录将是1000,所以当我填写表格时,5000是最新的ID,但是我试图访问表中的第5000条记录,而不是包含ID 5000的4000个值!

我会尝试和重写代码考虑到这一点,这是从来没有问题,因为当我没有删除他们匹配。 D'OH!