![]() |
Datenbank: Advantage Local Server • Version: 7 • Zugriff über: TQuery
Operation bei geschlossener Datenmenge nicht ausführbar
Guten Morgen,
in unserem Projekt hab ich in den letzten zwei Wochen zwei Fehlermeldungen von Anwendern bekommen, die ich hier in unseren Umgebungen nicht nachvollziehen kann. Die "sporadischen" Fehler halt, die jeder Programmierer so sehr liebt. :mrgreen: Und zwar folgendes ... Zitat:
Ist es vielleicht der zweite Zugriff auf "Query.RecordCount" in RDataModule.AssignSendingScheduleItems für "FPrgFrm.ShowProgressForm(Language.GetString(LID_L ABEL_STATUS_CREATING_OPTIMIZATION_PLAN) + ' ...', Query.RecordCount, nil, TRUE);"? (Code siehe unten) Kann ich mir aber nur schwer vorstellen ... :gruebel: ... Wie schon gesagt läuft der gleiche Spaß hier auf 4 verschiedenen Systemen blasenfrei. Auf einem Vista-Laptop laufen die Sendeaufträge sogar quasi 24/7 durch. Ich hab bisschen gegoogelt und ![]() Hier noch die Codes zu den Routinen CollectScheduleItems, GetSendingScheduleItems und AssignSendingScheduleItems. TSendingManager.Start aktiviert nur einen Timer, der wiederum CollectScheduleItems bei OnTimer aufruft.
Delphi-Quellcode:
procedure TSendingManager.CollectScheduleItems;
begin if Assigned (FOnClearHealingsheetsQue) then // nur Zugriff auf einen VST FOnClearHealingsheetsQue (Self); // FScheduleList-Items freigeben und FScheduleList.Clear; DisposeScheduleItems; // Sendeaufträge aus DB holen DBModule.GetSendingScheduleItems(TRUE, 0, FScheduleList); // nur Zugriff auf VST DisplayHealingsheetSchedule (DEFAULT_SENDING_SCHEDULE_ITEMS); end;
Delphi-Quellcode:
function TDBModule.RemoveInactiveSendingScheduleItems: Integer;
begin Result := 0; with AdsQuery, SQL do try Clear; Add ('DELETE FROM SendingSchedule ' + 'WHERE Active=FALSE'); ExecSQL; Close; Result := 1; except on E: Exception do ThrowSQLException (SQL[0], FALSE, E); end; end; procedure TDBModule.GetSendingScheduleItems (ActiveOnly: Boolean; MaxItems: Integer; var List: TSendingScheduleList); var s: String; begin // Inaktive Sendeaufträge im Vorfeld löschen RemoveInactiveSendingScheduleItems; with AdsQuery, SQL do //try begin Clear; if ActiveOnly then s := ' WHERE Active=TRUE ' else s := ''; Add ('SELECT * FROM ' + ' SendingSchedule ' + s + ' ORDER BY ' + ' SendingTimestamp'); Open; if (RecordCount > 0) then AssignSendingScheduleItems (List, AdsQuery); Close; { except // Catch von Exception ausgeschalten wg Fehlersuche on E: Exception do ThrowSQLException (SQL[0], FALSE, E);} end; end;
Delphi-Quellcode:
Habt ihr vielleicht noch eine Idee? :gruebel:
procedure TDBModule.AssignSendingScheduleItems (var List: TSendingScheduleList; Query: TADSQuery);
var a: Integer; ScheduleItem: PSendingScheduleItem; FPrgFrm: TProgressForm; begin FPrgFrm := TProgressForm.Create(nil); with Query do try a := 0; FPrgFrm.ShowProgressForm(Language.GetString(LID_LABEL_STATUS_CREATING_OPTIMIZATION_PLAN) + ' ...', Query.RecordCount, nil, TRUE); First; // ... entweder knallts hier ... try while not EOF do // ... oder hier ... begin FPrgFrm.UpdateProgressBar(a + 1); inc (a); ProcessMessages; New (ScheduleItem); ScheduleItem^.ID := FieldByName ('ID').AsInteger; ScheduleItem^.HealingsheetIndexID := FieldByName ('HealingsheetIndexID').AsInteger; ScheduleItem^.ClientID := FieldByName ('ClientID').AsInteger; ScheduleItem^.Duration := FieldByName ('Duration').AsInteger; ScheduleItem^.Frequency := FieldByName ('Frequency').AsInteger; ScheduleItem^.SendingTimestamp := FieldByName ('SendingTimestamp').AsDateTime; ScheduleItem^.EndingTimestamp := FieldByName ('EndingTimestamp').AsDateTime; ScheduleItem^.SendingType := TSendingType (Byte (FieldByName ('SendingType').AsInteger)); ScheduleItem^.Active := FieldByName ('Active').AsBoolean; List.Add(ScheduleItem); Next; end; except on E: Exception do ThrowSQLException (SQL[0], FALSE, E); end; finally FreeAndNil (FPrgFrm); end; end; |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Hallo Nuclear-Ping,
wo öffnest du denn die Query, bevor du First und EOF aufrufst? |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
In TDBModule.GetSendingScheduleItems (Code ist oben)
Delphi-Quellcode:
// ...
Open; if (RecordCount > 0) then AssignSendingScheduleItems (List, AdsQuery); Close; // ... |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Aber du schließt sie ja gleich wieder.
|
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Ja, aber erst nach dem AssignSendingScheduleItems (wenn RecordCount > 0) durchgelaufen ist. Die Ergebnisse aus der Query werden ja dort in die List übertragen und somit brauche ich die Ergebnissmenge auch nicht mehr, daher Close. Ist doch korrekt?
|
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Hmm, ich steig jetzt nicht wirklich so genau durch, was Dein Code da alles macht (arg aus dem Context gerissen) aber vielleicht solltest Du mal versuchen, die With-Konstrukte aufzuloesen.
(Nur so als Idee) |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Naja, im Grunde ist nur GetSendingScheduleItems relevant.
Das macht nix anderes als eine SELECT-Query auf 'ne lokale Datenbank und schiebt die Ergebnisse dann in eine TList. Wie schon geschrieben läuft das (auch mit dem "with-Konstrukt") hier auf 4 verschiedenen Systemen (auf einem im Dauerbetrieb) blasenfrei. Ich kann mir nicht vorstellen, dass es daran hängt. Insgesamt liegen wir glaube bei ~80 Anwendern. Aber zwei Anwender haben mir bisher von solchen sporadischen Exceptions berichtet und dem wollte ich mal auf den Grund gehen. |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Hallo,
liegt es vielleicht daran, das die Query aus welchem Grund auch immer nicht geöffnet werden konnte? Nen: RecordCount funzt nur, wenn die Query auch geöffnet ist. Das würde ich einbauen, mit entsprechender Untersuchung dann. Ich habe mit RecordCount auch schon mal Probleme gehabt und habe mich dann für folgendes Konstrukt entschieden:
Delphi-Quellcode:
Gruß
If (not Query.BOF) and (not Query.EOF) then
... Frank P.S. Bei den TOraQuery von AllroundAutomations gibt es glaube ich ne Eigenschaft, wie Connected TRUE/FALSE |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Danke für den Tip! :)
Das mit dem RecordCount hab ich auch im Verdacht. Hab die GetSendingScheduleItems-Prozedur erstmal so abgeändert:
Delphi-Quellcode:
... und auch die AssignSendingScheduleItems Routine angepasst und einem Anwender ein Update geschickt. Mal schauen, was er die Tage sagt.
procedure TDBModule.GetSendingScheduleItems (ActiveOnly: Boolean; MaxItems: Integer; var List: TSendingScheduleList);
var s: String; RecCnt: Cardinal; begin RemoveInactiveSendingScheduleItems; with AdsQuery, SQL do //try begin Clear; if ActiveOnly then s := ' WHERE Active=TRUE ' else s := ''; Add ('SELECT * FROM ' + ' SendingSchedule ' + s + ' ORDER BY ' + ' SendingTimestamp'); Open; RecCnt := RecordCount; // ** Neu ... if (RecCnt > 0) then AssignSendingScheduleItems (List, AdsQuery, RecCnt); Close; { except on E: Exception do ThrowSQLException (SQL[0], FALSE, E);} end; end; Falls es da immernoch Probleme gibt, bau ich den Vorschlag von dir mal rein. |
Re: Operation bei geschlossener Datenmenge nicht ausführbar
Hallo,
was ich hier auf jeden Fall vermisse, ist die Verwendung von try finally .
Delphi-Quellcode:
Ausserdem halt ich meine Queries auch immer nur solange offen,
Query.Open;
try // db code finally Query.Close end; wie notwendig. Das machst du aber ja auch schon. Beim RecordCount würde ich aber vorsichtig sein. Je nach verwendeter DB (ADS kenne ich nicht), liefert es entweder gar keinen Wert oder den der gefetchten Records. Besser ist ein bei SQL-Servern ein Select Count(*). Das RecordCount zählt z.B. unter FB (BDE, jaja ;) ) die Datensätze LOKAL durch. Dazu müssen sie erst mal vom Server geholt werden, das dauert ... Heiko Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz