Verwijderd schreef op donderdag 31 augustus 2006 @ 12:57:
code:
1
2
3
4
5
6
7
8
9
| procedure TApplicatie.buttonClick(Sender: TObject);
var qry : TStrings;
begin
qry.Clear;
qry.Add(' SELECT * from tabel ');
qry.Add(' WHERE kolom = 1 ');
QueryExec(data.qry1, qry, false);
end; |
ik krijg hier alleen steeds een error op:
---------------------------
Debugger Fault Notification
---------------------------
Project C:\Delphi Projects\app.exe faulted with message: 'access violation at 0x00404b06: write of address 0x0046268b'. Process Stopped. Use Step or Run to continue.
---------------------------
OK
---------------------------
hoe zit dat? iemand enig idee? Ik doe iets raars volgens mij maar ik kom er niet achter wat...
Maak hier 's van:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| procedure TApplicatie.buttonClick(Sender: TObject);
var qry : TStringList;
begin
qry := TStringList.Create;
try
qry.Add(' SELECT * from tabel ');
qry.Add(' WHERE kolom = 1 ');
// log hier evt. je query string
QueryExec(data.qry1, qry, false);
finally
qry.Free;
end;
end; |
Jij definieert qry als een locale variabele voor je procedure, maar je maakt 'm nergens aan. Zonder 'm expliciet te creeren is 't echter een loze pointer naar een willekeurig stuk geheugen.
TStrings kun je overigens niet direct zelf aanmaken, omdat 't een abstacte base class is waar o.a. TStringList van is afgeleid, maar bv. ook de items van een TreeView. Vandaar dat ik 'm nu maar even als TStringList heb gedefinieerd.
Dat loggen van die query kun je overigens ook in je QueryExec doen, vlak voor ExecSQL of Open wordt aangeroepen. Dan hoeft 't maar op 1 plek.
Edit: TStrings is zelf niet abstract, maar een paar essentiele methods (Clear, Delete, Insert) zijn dat wel, en moeten dus door de afgeleide geimplementeerd worden.
En nog een dingetje: in je QueryExec gebruik je "SQL := qry;". 't Is netter om dan "SQL.Assign(qry)" te gebruiken. Dan wordt niet botweg de pointer van SQL op qry gezet, maar neemt SQL de data van qry over.
Edit2: Assign() is niet alleen netter, maar "SQL := qry;" is doodgewoon fout.
Als je "SQL := qry;" gebruikt, is je vorige SQL TStrings opeens een loos object waar je nooit meer bijkomt en die je dus ook niet kunt opruimen. Gevolg: een pracht van een memory leak...
Bovendien, wanneer de echte eigenaar van qry besluit om die TStrings(-afgeleide) op te ruimen, krijg je bij de eerstvolgende aanroep van QueryExec weer een mooie exception, omdat "SQL.Clear" een lijst probeert leeg te maken die niet meer bestaat.
Oftewel: laat het SQL object over aan je TQuery, en neem alleen de data over uit die qry parameter.
[
Voor 21% gewijzigd door
Verwijderd op 31-08-2006 21:03
]