Entwickler-Ecke

Datenbanken - BDE: Zu viele offene Tabellen vorhanden


jjturbo - Fr 09.07.10 09:33
Titel: BDE: Zu viele offene Tabellen vorhanden
Moin Forum,

ich habe in einem Projekt einen Fehler, den ich vor ein paar Jahren schon einmal in einem anderen Projekt hatte.
Die Funktion die mir den Ärger bereitet (Siehe unten) wird oft aufgerufen, etwa 300 mal pro Stunde.
Ichn habe mir eine Testumgebung geschaffen, in der ich den Fehler in etwa 10 Minuten reproduzieren kann.

Die Fehlermeldung lautet: "Zu viele offene Tabellen vorhanden".

Sie tritt immer auf in einer der Zeilen "MyQuery.Active := True;", ich prüfe noch, ob es evtl. immer in der gleichen Zeile auftritt.
Im Moment wird MyQuery zur Laufzeit erstellt und auch wieder freigegeben. Ich hatte vorher ein Query und eine DataSource verwendet, die auf Form1 verfügbar waren, aber auch mit diesem Fehler.

Hat jemand eine Idee?



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
procedure FA_ZurueckmeldenAnSAP(FA_Rueck:String);
var Funct2            :Variant;
    TableOfConditions :Variant;
    TableCondRow      :Variant;
    s                 :String;
    SQLText            :String;
    Anz               :Integer;
    Erg               :Integer;
    ZeitStempel       :String;
    CounterWert       :Integer;
    DatenAnSapProt    :Array of String;
    Nr                :Integer;
//    f                 :TextFile;
//    Dateiname         :String;
//    J,M,T,Std,Min,Sek :String;
//    i                 :Integer;
    MyQuery           :TQuery;
    MyDataSource      :TDataSource;
begin

  if FA_Rueck = ''
   then Exit;




  Funct2            := 0;
  TableOfConditions := 0;
  TableCondRow      := 0;


  if not sapConnected then begin
    Showmessage('Nicht mit SAP verbunden. Abbruch.');
    Exit;
  end;





  protokoll(clGreen,'Fertigungsauftrag zurückmelden: ' + FA_Rueck);







  MyDataSource   := TDataSource.Create(nil);

  MyQuery        := TQuery.Create(nil);
  with MyQuery do begin
    DataSource   := MyDataSource;
    DatabaseName := Dir;
  end;





  s := FA_Rueck;
  while Length(s) < 12
   do s := '0' + s;


  Funct2 := Form1.mySAPFunctions.add('Z_RFC_RUECKMELDUNG_SAEGE');
  Funct2.exports('Auftrag').value := s;



  //Tabelle SAP füllen
  TableOfConditions := Funct2.tables.item('DATATAB');
  TableOfConditions.rows.removeAll;




  MyQuery.Active := false;
//  SQLText       := 'select * from ' + RueckPufferTabelle + ' WHERE FA=' + FA_Rueck + ' AND (status = "" OR status = "1")';
  SQLText       := 'select * from ' + RueckPufferTabelle + ' WHERE FA=' + FA_Rueck + ' AND NOT status="' + Text_Uebertragung_OK + '" AND Counter_Max_10 < 10';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.ExecSQL;
  MyQuery.Active := True;
  Anz := MyQuery.RecordCount;

  if Anz = 0 then begin
    Protokoll(clBlue,'Keine zurückzumeldenden Teile in diesem FA');
    MyQuery.Active := false;
    MyQuery.Free;
    MyDataSource.Free;
    Exit;
  end;



  //Alle Teile markieren, die jetzt zurück gemeldet werden
  if not NurEinenDatensatzZurueckmelden then begin
    SQLText := 'UPDATE ' + RueckPufferTabelle + ' SET rueckmeldenaktiv = 1 WHERE FA = ' + FA_Rueck + ' AND NOT status="' + Text_Uebertragung_OK + '" AND Counter_Max_10 < 10';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;
  end;
  if NurEinenDatensatzZurueckmelden
   then Anz := 1;
  
  NurEinenDatensatzZurueckmelden := false;




  SetLength(DatenAnSapProt,Anz+4);
  DatenAnSapProt[0] := 'SAPFunctions.add(Z_RFC_RUECKMELDUNG_SAEGE)';
  DatenAnSapProt[1] := 'FA: ' + FA_Rueck;
  Nr := 2;


  //Alle markierten Datensätze holen
  SQLText       := 'select * from ' + RueckPufferTabelle + ' WHERE rueckmeldenaktiv = 1';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.ExecSQL;
  MyQuery.Active := True;
  MyQuery.First;
  while not MyQuery.Eof do begin
    TableCondRow := TableOfConditions.rows.add;
    TableCondRow.Value[1]:= MyQuery.FieldByName('Nacharbeit_J_N').AsString;//'J';
    TableCondRow.Value[2]:= MyQuery.FieldByName('Materialnummer').AsString;//'0100';
    TableCondRow.Value[3]:= MyQuery.FieldByName('Aus Lagerort 0100/0200').AsString;//'0100';
    TableCondRow.Value[4]:= MyQuery.FieldByName('Länge').AsString;//'555';
//    if UpperCase(MyQuery.FieldByName('Rest_J_N').AsString) = 'R'
//     then TableCondRow.Value[4]:= 'R'
//     else TableCondRow.Value[4]:= MyQuery.FieldByName('Nacharbeit_J_N').AsString;//'J';
    MyQuery.Next;
    DatenAnSapProt[Nr] := 'DataTab Zeile' + IntToStr(Nr-1) + ': ' + TableCondRow.Value[1]
                                                           + ';'  + TableCondRow.Value[2]
                                                           + ';'  + TableCondRow.Value[3]
                                                           + ';'  + TableCondRow.Value[4];
    inc(Nr);
  end;


//Beispiel für eine Rückmeldedatei
//Mat-Nr;FA;Länge;Lagerort;x_von_x;Datum,Zeit,Nacharbeit,Rest
//P0106004_V1_031;2315489;1000;0100;1_von_2,000;20.04.2010;09:04:12;N;;
//P0106004_V1_031;2315489;2000;0100;2_von_2,000;20.04.2010;09:04:12;;;
//P0106004_V1_031;9999999;3000;0100;;20.04.2010;09:04:12;;R;


  Erg := 9999;
  TRY
  Erg := Funct2.call;
  EXCEPT
    protokoll(clRed,'Fehler in Funct2.call!');
    Showmessage('Fehler in Funct2.call!');
  END;

  DatenAnSapProt[Nr] := 'Ergebnis Funktionsaufruf (32Bit Integer): ' + IntToStr(Erg);
  inc(Nr);
  DatenAnSapProt[Nr] := 'Exception-Text des RFC-Bausteins: ' + Funct2.Exception;
//  inc(Nr);

//  J   := Copy(DateToStr(Now),7,4);//10.10.2010
//  M   := Copy(DateToStr(Now),4,2);
//  T   := Copy(DateToStr(Now),1,2);
//  Std := Copy(TimeToStr(Now),1,2);//12:34:56
//  Min := Copy(TimeToStr(Now),4,2);//12:34:56
//  Sek := Copy(TimeToStr(Now),7,2);//12:34:56

//  Dateiname := Dir+J+'_'+M+'_'+T+'_'+Std+'_'+Min+'_'+Sek+'_LastFunctionCall.txt';
{  AssignFile(f,Dateiname);
  Rewrite(f);
  Writeln(f,DatenAnSapProt[0]);
  Writeln(f,DatenAnSapProt[1]);
  for i := 2 to Length(DatenAnSapProt)-1
   do Writeln(f,DatenAnSapProt[i]);
  CloseFile(f);}



  if Funct2.Exception = Text_Uebertragung_OK then begin


    MyQuery.Active := false;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET status = "' + Funct2.Exception +  '" WHERE rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    ZeitStempel   := DateToStr(Now) + ', ' + TimeToStr(Now);
    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET zeitpunkt = "' + ZeitStempel + '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    Protokoll(clGreen,'Übertragung erfolgreich! Anzahl: ' + IntToStr(Anz));
    protokoll(clGreen,'Meldung des RFC-Bausteins: ' + Funct2.Exception);
    //KEINFA
  end
  else begin
    SQLText       := 'SELECT * FROM ' + RueckPufferTabelle + ' WHERE rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    MyQuery.Active := True;
    CounterWert := StrToIntDef(MyQuery.FieldByName('Counter_Max_10').AsString,0)+1;
    MyQuery.Active := false;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET Counter_Max_10 = "' + IntToStr(CounterWert) + '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET status = "' + Funct2.Exception +  '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    protokoll(clRed,'Übertragung nicht erfolgreich! Meldung des RFC-Bausteins: ' + Funct2.Exception);
    Application.BringToFront;
  end;

  //Markierungen wieder entfernen
  SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET rueckmeldenaktiv = 0  WHERE fa > 1';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.ExecSQL;



  MyQuery.Active := false;
  MyQuery.Free;
  MyDataSource.Free;

end;


mkinzler - Fr 09.07.10 09:37

Ich würde mir an deiner Stelle überlegen, ob ich weiter mit der BDE arbeiten würde. Du scheinst ja sowieso über ODBC o.ä. auf SAP zuzugreifen.
Das wären dann 2 bremsende Krücken.


jjturbo - Fr 09.07.10 09:46

Könnte ich auf meine Paradox-Tabellen z.B. auch einfach mit Zeos zugreifen?


mkinzler - Fr 09.07.10 09:53

Ach das sind Paradox-Tabellen. Dann würde ich Paradox auch gegen ein zeitgemässes DBMS ersetzen.
Für Paradox und dBase ist die BDE mehr als eine Zugriffskomponente, deshalb geht Zeos nicht


jjturbo - Fr 09.07.10 09:56

Was kannst Du denn als Ersatz empfehlen? Ich hättet gerne nach wie vor lokale Tabellen ohne einen Datenbankserver.


mkinzler - Fr 09.07.10 10:01

Ich persönlich würde dir dann zu FireBird (embedded) raten. Zum Entwickeln mit Server und später dann die embedded (Server)Client Lösung.


jjturbo - Fr 09.07.10 10:05

Bei den neueren Projekten nehmen wir Firebird mit Zeos.
ich denke mal drüber nach.

Aber zurück zu meinem Problem: Wenn die Funktion das 126. Mal aufgerufen wirds, dann passierts.


mkinzler - Fr 09.07.10 10:10

Du scheinst den Query nur im Fehlerfall zu schliessen ( oder ich habe es übersehen)


jjturbo - Fr 09.07.10 10:14

Du meinst mit MyQuery.Active := false?
Habe ich es irgendwo vergessen? Wenn, dann sehe ich die Stelle nicht.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Korrektur: Immer im 125. Aufruf, immer an der zweiten Stelle mit MyQuery.Active := True;


mkinzler - Fr 09.07.10 10:25

In Zeile 98 verwendest du das bestehende Queryobjekt ohne das offene DataSet zu schliessen
In Zeile 198 ist ExecuteSQL falsch ( da Abfrage nicht DML)
Statt .Active auf True/False zu setzen würde ich .Open / .Close verwenden


jjturbo - Fr 09.07.10 10:36

Zu Zeile 98: Muß ich vor jedem ExecSQL MyQuery.Active := false setzen?

Worin unterscheiden sich denn .Active True/false und .Open/.Close


mkinzler - Fr 09.07.10 10:43

Jein. Es kommt adrauf an, was vorher gemacht wurde. Nach .ExecSQL ist es imho nicht notwendig, aber nach einer Abfrage, welche ja eine Datenmenge zurückliefert ( auch eine leere Datenmenge ist eine).

.Active := True ruft .Open bzw. .ExecuteSQL auf auf, ich bevorzuge es aber selbst zu machen


jjturbo - Fr 09.07.10 11:03

Habe es mal etwas abgeändert, so läuft es auf jeden schon mal länger, steht jetzt bei etwa 200 Funktionsaufrufen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
procedure FA_ZurueckmeldenAnSAP(FA_Rueck:String);
var Funct2            :Variant;
    TableOfConditions :Variant;
    TableCondRow      :Variant;
    s                 :String;
    SQLText            :String;
    Anz               :Integer;
    Erg               :Integer;
    ZeitStempel       :String;
    CounterWert       :Integer;
    DatenAnSapProt    :Array of String;
    Nr                :Integer;
    MyQuery           :TQuery;
    MyDataSource      :TDataSource;
begin

inc(Nummer);
  form1.caption := IntToStr(nummer);
  if FA_Rueck = ''
   then Exit;




  Funct2            := 0;
  TableOfConditions := 0;
  TableCondRow      := 0;


  if not sapConnected then begin
    Showmessage('Nicht mit SAP verbunden. Abbruch.');
    Exit;
  end;





  protokoll(clGreen,'Fertigungsauftrag zurückmelden: ' + FA_Rueck);







  MyDataSource   := TDataSource.Create(nil);

  MyQuery        := TQuery.Create(nil);
  with MyQuery do begin
    DataSource   := MyDataSource;
    DatabaseName := Dir;
  end;





  s := FA_Rueck;
  while Length(s) < 12
   do s := '0' + s;


  Funct2 := Form1.mySAPFunctions.add('Z_RFC_RUECKMELDUNG_SAEGE');
  Funct2.exports('Auftrag').value := s;



  //Tabelle SAP füllen
  TableOfConditions := Funct2.tables.item('DATATAB');
  TableOfConditions.rows.removeAll;




  MyQuery.Active := false;
  SQLText        := 'select * from ' + RueckPufferTabelle + ' WHERE FA=' + FA_Rueck + ' AND NOT status="' + Text_Uebertragung_OK + '" AND Counter_Max_10 < 10';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.Active := True;
  Anz := MyQuery.RecordCount;

  if Anz = 0 then begin
    Protokoll(clBlue,'Keine zurückzumeldenden Teile in diesem FA');
    MyQuery.Active := false;
    MyQuery.Free;
    MyDataSource.Free;
    Exit;
  end;



  //Alle Teile markieren, die jetzt zurück gemeldet werden
  if not NurEinenDatensatzZurueckmelden then begin
    SQLText := 'UPDATE ' + RueckPufferTabelle + ' SET rueckmeldenaktiv = 1 WHERE FA = ' + FA_Rueck + ' AND NOT status="' + Text_Uebertragung_OK + '" AND Counter_Max_10 < 10';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;
  end;
  if NurEinenDatensatzZurueckmelden
   then Anz := 1;
  
  NurEinenDatensatzZurueckmelden := false;




  SetLength(DatenAnSapProt,Anz+4);
  DatenAnSapProt[0] := 'SAPFunctions.add(Z_RFC_RUECKMELDUNG_SAEGE)';
  DatenAnSapProt[1] := 'FA: ' + FA_Rueck;
  Nr := 2;


  //Alle markierten Datensätze holen
  MyQuery.Active := false;
  SQLText        := 'select * from ' + RueckPufferTabelle + ' WHERE rueckmeldenaktiv = 1';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.Active := True;
  MyQuery.First;
  while not MyQuery.Eof do begin
    TableCondRow := TableOfConditions.rows.add;
    TableCondRow.Value[1]:= MyQuery.FieldByName('Nacharbeit_J_N').AsString;//'J';
    TableCondRow.Value[2]:= MyQuery.FieldByName('Materialnummer').AsString;//'0100';
    TableCondRow.Value[3]:= MyQuery.FieldByName('Aus Lagerort 0100/0200').AsString;//'0100';
    TableCondRow.Value[4]:= MyQuery.FieldByName('Länge').AsString;//'555';
    MyQuery.Next;
    DatenAnSapProt[Nr] := 'DataTab Zeile' + IntToStr(Nr-1) + ': ' + TableCondRow.Value[1]
                                                           + ';'  + TableCondRow.Value[2]
                                                           + ';'  + TableCondRow.Value[3]
                                                           + ';'  + TableCondRow.Value[4];
    inc(Nr);
  end;
  MyQuery.Active := false;


//Beispiel für eine Rückmeldedatei
//Mat-Nr;FA;Länge;Lagerort;x_von_x;Datum,Zeit,Nacharbeit,Rest
//P0106004_V1_031;2315489;1000;0100;1_von_2,000;20.04.2010;09:04:12;N;;
//P0106004_V1_031;2315489;2000;0100;2_von_2,000;20.04.2010;09:04:12;;;
//P0106004_V1_031;9999999;3000;0100;;20.04.2010;09:04:12;;R;


  Erg := 9999;
  TRY
  Erg := Funct2.call;
  EXCEPT
    protokoll(clRed,'Fehler in Funct2.call!');
    Showmessage('Fehler in Funct2.call!');
  END;

  DatenAnSapProt[Nr] := 'Ergebnis Funktionsaufruf (32Bit Integer): ' + IntToStr(Erg);
  inc(Nr);
  DatenAnSapProt[Nr] := 'Exception-Text des RFC-Bausteins: ' + Funct2.Exception;
//  inc(Nr);

//  J   := Copy(DateToStr(Now),7,4);//10.10.2010
//  M   := Copy(DateToStr(Now),4,2);
//  T   := Copy(DateToStr(Now),1,2);
//  Std := Copy(TimeToStr(Now),1,2);//12:34:56
//  Min := Copy(TimeToStr(Now),4,2);//12:34:56
//  Sek := Copy(TimeToStr(Now),7,2);//12:34:56

//  Dateiname := Dir+J+'_'+M+'_'+T+'_'+Std+'_'+Min+'_'+Sek+'_LastFunctionCall.txt';
{  AssignFile(f,Dateiname);
  Rewrite(f);
  Writeln(f,DatenAnSapProt[0]);
  Writeln(f,DatenAnSapProt[1]);
  for i := 2 to Length(DatenAnSapProt)-1
   do Writeln(f,DatenAnSapProt[i]);
  CloseFile(f);}



  if Funct2.Exception = Text_Uebertragung_OK then begin


    MyQuery.Active := false;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET status = "' + Funct2.Exception +  '" WHERE rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    ZeitStempel   := DateToStr(Now) + ', ' + TimeToStr(Now);
    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET zeitpunkt = "' + ZeitStempel + '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    Protokoll(clGreen,'Übertragung erfolgreich! Anzahl: ' + IntToStr(Anz));
    protokoll(clGreen,'Meldung des RFC-Bausteins: ' + Funct2.Exception);
    //KEINFA
  end
  else begin
    SQLText       := 'SELECT * FROM ' + RueckPufferTabelle + ' WHERE rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.Active := True;

    CounterWert := StrToIntDef(MyQuery.FieldByName('Counter_Max_10').AsString,0)+1;
    MyQuery.Active := false;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET Counter_Max_10 = "' + IntToStr(CounterWert) + '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET status = "' + Funct2.Exception +  '" WHERE  rueckmeldenaktiv = 1';
    MyQuery.SQL.SetText(PChar(SQLText));
    MyQuery.ExecSQL;

    protokoll(clRed,'Übertragung nicht erfolgreich! Meldung des RFC-Bausteins: ' + Funct2.Exception);
    Application.BringToFront;
  end;

  //Markierungen wieder entfernen
  SQLText       := 'UPDATE ' + RueckPufferTabelle + ' SET rueckmeldenaktiv = 0  WHERE fa > 1';
  MyQuery.SQL.SetText(PChar(SQLText));
  MyQuery.ExecSQL;



  MyQuery.Active := false;
  MyQuery.Free;
  MyDataSource.Free;

end;


mkinzler - Fr 09.07.10 11:10

Nimm mal verschiedene Query-Komponenten. Diese würde ich parametrisieren


jjturbo - Fr 09.07.10 11:20

Wie meinst Du das?

Aber das Problem scheint damit behoben zu sein, die Funktion wurde bis jetzt etwa 700 mal aufgerufen.
Muß man vor jedem ExecSQL Query.Active := false setzen? Bleibt sonst irgendetwas in den Tiefen der BDE geöffnet?


mkinzler - Fr 09.07.10 11:26

Es sieht ja wirklich danach aus