AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Schneller SQL Zugriff macht Probleme
Thema durchsuchen
Ansicht
Themen-Optionen

Schneller SQL Zugriff macht Probleme

Ein Thema von alphaflight83 · begonnen am 14. Aug 2008 · letzter Beitrag vom 19. Aug 2008
Antwort Antwort
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
148 Beiträge
 
Delphi 12 Athens
 
#1

Schneller SQL Zugriff macht Probleme

  Alt 14. Aug 2008, 14:33
Datenbank: Access MDB • Zugriff über: ADO
Hallo DP-Gemeinde,
ich hätte mal wieder ein Problem:
Ich möchte eine Liste der aktuellen Fehler mehrerer Clients,
die auf einem Server gespeichert sind (Für jeden Client ein eigenes File)
in einem Form anzeigen, wobei noch zusätzliche Information aus einer lokalen Datenbank
(Access .mdb) ausgelesen und dazugenommen werden soll.
Zu diesem Zweck werden die einzelnen Files in eine eigene lokale Tabelle geschrieben und dann
über ein JOIN mit der zusätzlichen Information verknüpft und per DBGrid ausgegeben.
Das funktioniert auch soweit, allerdings momentan eher als Faulthistory, da alle Fehler gespeichert werden und bleiben.
Bevor ich nun die neuen Datensätze schreibe, muss ich also die alten löschen. Das erledige ich über eine zweite ADOQuery
uznd nun kommt das hüpfende Komma:
Sobald ich lösche funktioniert das Ganze eine Weile wie es soll, verabschiedet sich jedoch relativ schnell mit:
EOleException: Aktualisierung nicht möglich; momentan gesperrt.
Irgendwie kommen sich dabei anscheinend die Abfragen ins Gehege.

Ich sollte noch erwähnen, dass für alle Clients das selbe Fenster geöffnet wir, und über die ID die Fehlermeldungen ausgewählt werden.
Genug Gefasel hier der Quelltext

Delphi-Quellcode:
(***************************
**  Function: ShowAlarms  **
****************************
** Show the active alarms **
**  with a database grid  **
***************************)

function TForm_ActiveFault.ShowAlarms():Integer;
var
  i : Integer;
  ID_Str : String;
  Status : Integer;

begin

  Status := 0;

  try

    (* TODO: Testversion: The deleteprogress produces an error *)
    DataModule1.ADOQueryFaultAct.Close;

    (* TODO : Testversion: deletes the active faults of the current client from the ADO table *)
    Datamodule1.ADOQueryFaultDel.Close;
    Datamodule1.ADOQueryFaultDel.SQL.Clear;
    Datamodule1.ADOQueryFaultDel.SQL.Text := 'DELETE * FROM Fault_Active WHERE Client_ID = ' + IntToStr (Curr_Client_ID);
    Datamodule1.ADOQueryFaultDel.ExecSQL;
    Datamodule1.ADOQueryFaultDel.Close;

    Datamodule1.ADOTableFaultAct.Active := True;
    Datamodule1.ADOTableFaultAct.First;

    ID_Str := IntToStr(Curr_Client_ID);

    (* Read the active faults from the server into the stringgrid *)
    Read_CSV_File (ACTIVEALARMS_Path + 'active' + ID_Str, #9, StringGrid_Hide);

    (* Write the content of the stringgrid into the ADO Table *)
    for i := 1 to Pred(StringGrid_Hide.RowCount) do
    begin
      StringGrid_Hide.Cells[1,i-1] := DateTimeToStr(Now);
      if StringGrid_Hide.Cells[3,i-1] = 'then StringGrid_Hide.Cells[3,i-1] := '0';

      Datamodule1.ADOTableFaultAct.Append;

      Datamodule1.ADOTableFaultAct.FieldByName ('Client_ID') .AsString := ID_Str;
      Datamodule1.ADOTableFaultAct.FieldByName ('Name') .AsString := StringGrid_Hide.Cells[0,i-1]; // Faultname
      Datamodule1.ADOTableFaultAct.FieldByName ('StartTime') .AsString := StringGrid_Hide.Cells[1,i-1]; // StartTime
      Datamodule1.ADOTableFaultAct.FieldByName ('Code') .AsString := StringGrid_Hide.Cells[2,i-1]; // Code
      Datamodule1.ADOTableFaultAct.FieldByName ('Subcode') .AsString := StringGrid_Hide.Cells[3,i-1]; // Subcode
      Datamodule1.ADOTableFaultAct.FieldByName ('Priority') .AsString := StringGrid_Hide.Cells[4,i-1]; // Priority
      Datamodule1.ADOTableFaultAct.Next;
    end;

    DataModule1.ADOTableFaultAct.Close;
    // DataModule1.ADOTableFaultAct.EnableControls;

    DataModule1.ADOQueryFaultAct.SQL.Clear;

    (* Read the active alarms of the current client from the Fault_Active table and *)
    (* connect them with the information from the 'Fault_Definition' table *)
    DataModule1.ADOQueryFaultAct.SQL.Text :=
      'SELECT Fault_Active.Code As Code, ' +
      ' Fault_Active.SubCode As Subcode, ' +
      ' Fault_Definition.Priority As Priority, ' +
      ' Fault_Active.StartTime As StartTime, ' +
      ' Fault_Definition.DisplayName As FaultText, ' +
      ' Fault_Definition.description As Description, ' +
      ' Fault_Definition.manualRef As Reference ' +
      ' FROM Fault_Definition, Fault_Active ' +
      ' WHERE Fault_Definition.Name = Fault_Active.Name ' +
      ' AND Fault_Definition.Client_ID = Fault_Active.Client_ID ' +
      ' AND Fault_Definition.Client_ID = ' + IntToStr (Curr_Client_ID) +
      ' ORDER BY Fault_Active.StartTime ASC';

    DataModule1.ADOQueryFaultAct.ExecSQL;
    DataModule1.ADOQueryFaultAct.Open;

    (* Pass the FieldNames of the queryresult to the DBGrid *)
    DBGrid_Active.Columns[0].FieldName := 'Code';
    DBGrid_Active.Columns[1].FieldName := 'Subcode';
    DBGrid_Active.Columns[2].FieldName := 'Priority';
    DBGrid_Active.Columns[3].FieldName := 'StartTime';
    DBGrid_Active.Columns[4].FieldName := 'FaultText';
    DBGrid_Active.Columns[5].FieldName := 'Description';
    DBGrid_Active.Columns[6].FieldName := 'Reference';

    for i := 1 to Pred(StringGrid_Hide.RowCount) do
    begin
      if StrToInt(StringGrid_Hide.Cells[4,i-1]) > Status
     then Status := StrToInt(StringGrid_Hide.Cells[4,i-1]);
    end;

  except
    begin
      Release_ActiveFault := False;
      Messagebox(Handle, PChar('Disturbed database connection'), PChar('Database fault'), MB_OK or MB_ICONWARNING);
    end;
  end;

  Result := Status;
  
end;
Hoffe es kann jemand helfen

PS: Ich weiß, dass die Idee in die Datenbank zu schreiben und kurz darauf wieder zu löschen nicht die tollste ist,
mir ist aber keine bessere Möglichkeit eingefallen, die in der zweiten Datenbank gespeicherten Infos mit den Files der
einzelnes Clients zu verknüpfen ...
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
148 Beiträge
 
Delphi 12 Athens
 
#2

Re: Schneller SQL Zugriff macht Probleme

  Alt 14. Aug 2008, 16:28
Das Problem hat sich erledigt.

1. Wurde der Timer der die Funktion gestartet hat nicht beendet, wodurch dann bei Schließen und Neuöffnen des Fensters für einen anderen Client die Querys doppelt verwendet wurden, was zum Crash führte

2. Wurden die Querys anscheinend zu schnell nacheinander ausgeführt, so dass der Tabellenzugriff noch nicht wirklich beendet war.
Ein Delay zwischen den Querys schfft Abhilfe.

Das erste DataModule1.ADOQueryFaultAct.Close; musste letztendlich auch weichen, da sonst immer eine kurze Zeitspanne nichts im DBGrid angezeigt wurde, bis die neuen Daten da waren.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: Schneller SQL Zugriff macht Probleme

  Alt 14. Aug 2008, 17:09
Zitat von alphaflight83:
2. Wurden die Querys anscheinend zu schnell nacheinander ausgeführt, so dass der Tabellenzugriff noch nicht wirklich beendet war.
Ein Delay zwischen den Querys schfft Abhilfe.
Das ist keine schöne Lösung.
Wichtig: deine Anwendung braucht genau eine TADOConnection Komponente.
Alle TADOQuery, TADOTable, TADODataset und TADOCommand müssen auf diese eine Connection verweisen.

Sollte es nämlich mehrere Datenbankverbindungen geben, dann sieht die Verbindung B die Daten von Verbindung A erst nach ~ 2.5 Sekunden Verzögerung.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
148 Beiträge
 
Delphi 12 Athens
 
#4

Re: Schneller SQL Zugriff macht Probleme

  Alt 18. Aug 2008, 13:32
Hi, hab das grade mal probiert, über eine TADO Connection zu gehen (Zuvor hab ich für jede table einen Connection String bei Laufzeit zugewiesen)
Mit nur einer TADO Connection bekomm ich jetzt aber auch wieder Zugriffsverletzungen in der Art wie zuvor.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: Schneller SQL Zugriff macht Probleme

  Alt 18. Aug 2008, 18:06
Zitat von alphaflight83:
Mit nur einer TADO Connection bekomm ich jetzt aber auch wieder Zugriffsverletzungen in der Art wie zuvor.
Du hast ja auch jede Menge Unsauberkeiten in deinem Code.
Zum Beispiel sind die Zeilen nach (* Pass the FieldNames of the queryresult to the DBGrid *) falsch,
da ein DBGrid seine Spalten eigenständig an die Felder bindet.
Wenn das DBGrid weniger als 7 Spalten hat, gibt es eine Zugriffsverletzung.
Um die Felder in eine bestimmte Reihenfolge zu bringen, gibt es schönere Möglichkeiten.

Du hast kein Sicherheitsnetz aufgespannt.
Zum Beispiel DataModule1.ADOQueryFaultAct.Close - bist du 100% sicher, dass die Variable DataModule1 überhaupt auf ein Datenmodul zeigt ?
Delphi-Quellcode:
Assert(Assigned(DataModule1)); // sicherstellen, dass Datenmodul vorhanden
try
  DataModule1.ADOQueryFaultAct.Close;
  ...
Deine Exceptionbehandlung ist auch falsch, da du die eigentliche Fehlermeldung komplett unter den Tisch fallen lässt.

Du solltest auf jeden Fall nur mit einer ADOConnection arbeiten und deine Zugrfiffsverletzungen mit dem Debugger ausmerzen.
Andreas
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#6

Re: Schneller SQL Zugriff macht Probleme

  Alt 18. Aug 2008, 21:35
mal eine andere frage, weshalb verwendest du denn datensensitive komponenten?

das könntest du doch auch mit 'n normalen stringgrid abbilden und das füllen selbst übernehmen

damit erstparst du dir die ganzen komplikationen und das progy wird viel runder
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
148 Beiträge
 
Delphi 12 Athens
 
#7

Re: Schneller SQL Zugriff macht Probleme

  Alt 19. Aug 2008, 08:36
Erst mal Danke für die Antworten

@ shmia:

Okay, die unsauberen Stellen werd ich versuchen auszubessern.
Zu den schöneren Methoden die Reihenfolge festzulegen:
Könntest du da mal welche nennen?
Wenn ich meinem Grid nämlich sieben Spalten zuweise,
und ich denke das muss ich tun, um den Spalten ihre Größe zuzuweisen,
muss ich dann auch die Spaltennamen zuweisen, da sonst nichts im Grid erscheint.
Wenn ich damit auf dem Holzweg bin, bitte ich um Berichtigung.

@grenzgaenger:

Das Problem ist, dass ich eine Tabelle mit Fehlerbeschreibungen vorliegen habe, in denen eben alle für ein Gerät möglichen Fehler gelistet sind.
Hier muss ich nun mittels Select zumindest mal die benötigten raussuchen.
Hab ich schon die Select Anweisung kann ich deren Ergebnis auch gleich in ein DBGrid schreiben.
So war jedenfalls mein Gedankengang.
Wenn das effizienter bzw. einfacher geht lass ich mich gerne belehren.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz