2017-01-23 1 views
0

Ich habe eine Datenbankdatei erstellt, die die Messwerte jede Minute aktualisiert und in einer SQL Server CE-Datenbankdatei speichert. Da die Datenbank jedoch sehr groß wird, beginnt sie langsam zu werden.SQL Server CE & C# Nach dem Löschen von Datensätzen können keine Daten in einer Tabelle gelesen werden.

Ich beschloss, die ältesten Dateien zu löschen, sobald die Datenbank eine bestimmte Größe erreicht hat, da sie für mich keinen Nutzen mehr haben. Ich schaffte dies mit den folgenden Befehlen zu tun:

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

wo difference.ToString() Wert ich verwenden, um zu berechnen, wie viel ich will löschen.

Dies funktionierte erfolgreich, da ich die Datei mit CompactView öffnen konnte und auch die Befehle in CompactView eingeben konnte, um die gleichen Ergebnisse zu geben.

Jetzt begann mein Problem, als ich versuchte, die Daten zu lesen und in ein Diagramm zu aktualisieren. Also meine Codes in einer anderen Form geschieht Folgendes:

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); 

Das Problem, das ich habe ist, dass die Tabelle leer ist, obwohl Wert von (int)com.ExecuteScalar() einen Wert zurückgibt! Wenn ich das Löschen nicht durchgeführt habe, funktioniert alles einwandfrei!

Ich kann nicht herausfinden, was passiert! Das einzige, was mir einfällt, ist das Lesen und Schreiben der SQL-Datei.

Sehr geschätzt!

+0

Ihr Sprichwort, wenn Sie das Löschen ausführen, zeigt die Tabelle leer? – Moudiz

+0

Wie und wann führen Sie den Löschvorgang aus? Handelt es sich um einen manuellen Stapelprozess oder wird es automatisch von einem anderen Thread ausgeführt? Es scheint, dass es ein Synchronisierungsproblem geben könnte – salvolds

+0

Es gibt 2 Timer auf separaten Formularen, 1 Timer wird verwendet, um die Datenbank mit den neuesten Daten zu füllen und es läuft die ganze Zeit. Der andere Timer wird verwendet, wenn das Graphikprogramm gestartet wird. Beide aktualisieren die Daten jede Minute oder schneller. Wenn die Datenbank groß wird, werden die ältesten Daten gelöscht. Währenddessen versucht das Graphikprogramm, die angezeigten Werte zu aktualisieren, indem dieselbe Datenbank gelesen wird. Obwohl das neueste ID-Feld funktioniert und korrekte Werte liefert, zeigt es beim Ausfüllen der Tabelle nichts an. Prost – aaz

Antwort

0

Besser nicht TOP hier verwenden. Wenn die ID automatisch inkrementiert wird, holen Sie sich die höchste ID und löschen Sie dann maximal vor dieser ID, da die letzte ID im Grafikteil verwendet wird. Löschen Sie beispielsweise alles unter der aktuellen maximalen ID oder unter der maximalen ID - 10 oder so.

LÖSCHEN * von der Tabelle wo ID < MAX (ID);

Wenn TOP wie beim Löschen verwendet wird, werden alle Werte einschließlich der TOP (letzte ID) gelöscht. Und im Grafikteil greifen Sie auch auf die letzte ID zu.

+0

Danke, aber das Löschen funktioniert, es löscht die ältesten Datensätze und nicht die neuesten Datensätze. Zum Beispiel lösche ich sage 100 Datensätze von 400. So funktioniert die eigentliche Aussage, da der ExecuteScalar die richtige ID zurückgibt, aber keine Daten zeigt. – aaz

+0

Ich habe ein anderes Problem gefunden! Was mit dem zusammenhängt, was Sie sagen. Wenn ich einen Löschvorgang durchführe, dann fügt er Datensätze ein und fügt die neuen Daten an der Spitze der Datenbank statt an der Unterseite ein! – aaz

0

So haben Sie zwei Probleme:

  1. Tisch leer ist, nachdem der Lösch
  2. Ihre Anfrage ein Ergebnis trotz der Tatsache zurück, dass die Tabelle

In Bezug auf die erste leer ist ein Problem ist in Ihrer Anweisung löschen: aus irgendeinem Grund Ihre difference Wert ist höher oder gleich der Anzahl der Zeilen in Ihrer Tabelle und löscht die gesamte Tabelle. Ich würde auf die Art und Weise schauen, wie Sie es berechnen. Auf jeden Fall, wenn Sie einen insert_date auf dem Tisch haben, würde ich die Delete-Anweisung wie folgt ändern Zeilen, die älter als 10 Tage ab heute zu löschen:

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

Das zweite Problem ist ein Concurrency Problem der Tatsache, dass zwei miteinander verbundene Threads funktionieren: Es kann vorkommen, dass Sie Daten (und Daten sind verfügbar) lesen, bevor Daten gelöscht werden. Sie erhalten also nicht wirklich ein Abfrageergebnis von einer leeren Tabelle, auch wenn dies die Impression ist.

+0

Danke, der Differenzwert ist nicht höher als die Anzahl der Zeilen in der Tabelle, ich habe den Code durchgegangen, ich habe sogar die Software verlassen und die Datenbank mit CompactView angeschaut, um die Daten anzuschauen und es löscht den richtigen Betrag Es scheint nur nicht die Daten auf dem Tisch zu zeigen, identifiziert jedoch die richtige ID. – aaz

+0

@aaz: Ist es nur ein Problem bei der Select-Anweisung, die Sie dann in der Kompaktansicht ausführen? – salvolds

0

Ich denke, ich habe das Problem herausgefunden! Verzeih mir, wenn du mir das erklären wolltest und ich habe es nicht verstanden, aber hier geht es! Das Problem besteht darin, die Tabelle zu füllen, während der von ExecuteScalar zurückgegebene Wert korrekt ist. Diese ID ist größer als die Tabelle, da die Tabelle von 0 anstatt vom subtrahierten Betrag zählt!

Also zum Beispiel habe ich 1000 Datensätze von 5000 gelöscht, der älteste Datensatz wäre dann 1000, also wenn ich die Tabelle fülle die 5000 ist die neueste ID, aber ich versuche, den 5000. Datensatz in der Tabelle zugreifen, anstatt die 4000ster Wert, der ID 5000 enthält!

werde ich versuchen, und schreiben Sie den Code dies berücksichtigen, das war nie ein Problem vor, als wenn ich nicht löschen sie abgestimmt. D'OH!

Verwandte Themen