Wenn dies Ihr erster Besuch hier ist,
lesen Sie bitte zuerst die Hilfe - Häufig gestellte Fragen
durch. Sie müssen sich vermutlich registrieren,
bevor Sie Beiträge verfassen können. Klicken Sie oben auf 'Registrieren', um den Registrierungsprozess zu
starten. Sie können auch jetzt schon Beiträge lesen. Suchen Sie sich einfach das Forum aus, das Sie am meisten
interessiert.
es wäre hilfreich gewesen, die verwendete Datenbank zu nennen. Beim Zugriff auf eine InterBase-Datenbank sieht das zum Beispiel so aus. Über <b>EDBEngineError</b> liefert Delphi die Fehlermeldungen frei Haus. Im Feld <b>NativeError</b> steht dabei die originale Fehlernummer der Datenbank:
<pre>
function GetSQLCODE(E: Exception): Integer;
var
iIdx : Integer;
begin
Result := -1;
if E is EDBEngineError then
with EDBEngineError(E) do
for iIdx := 0 to ErrorCount - 1 do
if Errors[iIdx].NativeError <> 0 then
begin
Result := Errors[iIdx].NativeError;
Exit;
end;
end;
</pre>
Wenn beim INSERT/UPDATE eine Exception eintritt, kann das Programm nachschauen, welche Fehlernummer der InterBase-Server zurückgeliefert hat. Eine Beschreibung der nativen Fehlernummern findet sich in den InterBase-Handbüchern:
<pre>
procedure TFormMain.ButtonUpdateClick(Sender: TObject);
var
iOldValue : Integer;
iNewValue : Integer;
begin
ButtonUpdate.Enabled := False;
ShowStatusBarMsg('');
iOldValue := StrToInt(StaticTextWert.Caption);
iNewValue := iOldValue + StrToInt(EditWert.Text);
ShowStatusBarMsg('Update-Button angeklickt...');
try
with QueryUpdate do begin
Params[0].Value := iNewValue;
ExecSQL;
ShowStatusBarMsg(Format('UPDATE - %d Datensatz geändert',
[RowsAffected]));
end;
QuerySELECT.Active := True;
StaticTextResult.Caption := QuerySELECTWERT.AsString;
QuerySELECT.Active := False;
ShowStatusBarMsg('SELECT nach Update liest Endwert');
Database1.Commit;
ShowStatusBarMsg('COMMIT');
except
Database1.Rollback;
ShowStatusBarMsg('ROLLBACK');
if CheckBoxDlg.Checked then
DBError.HandleException(Exception(ExceptObject))
else
begin
if GetSQLCODE(Exception(ExceptObject)) = -913 then
MessageDlg('Sorry - leider war ein anderer Benutzer schneller.',
mtError, [mbOk], 0)
else
Raise;
end;
ButtonSelect.Click;
end;
ButtonSelect.Enabled := True;
end;
</pre>
ich verwende Interbase in Verbindung mit TQuery und ChachedUpdates.
Wenn nun bei ApplyUpdates ein Fehler auftritt, und man hat mehrere TQuerys (Master-Detail), so gibt es beim Versuch des erneuten Speicherns Probleme ('Tabellenende') bei mindestens einer Tabelle, die im ersten Versuch bereits erfolgreich upgedatet wurde.
Noch im alten Forum hast Du mir den Tip gegeben, den Fehler in OnUpdateError von TQuery zu behandeln. Auch Borland empfiehlt dies in der Delphi-Hilfe (wenn man etwas sucht) sogar ausdrücklich. Das mache ich jetzt auch, allerdings werte ich in OnUpdateError den BDE-Fehlercode von EDBEngineError aus (Indexfehler 97xx). In diesem Fall weise ich dem Schlüsselfeld einen neuen Wert zu und setze UpdataAction auf UAretry, bei anderen Fehlern, die ich nicht selber korrigieren kann, setze ich Uaignore.
Eigentlich reicht mir doch die BDE-Fehlernummer, da die BDE den Indexfehler (und auch viele andere Fehler) eindeutig erkennt?!
die BDE-Fehlernummer ist in diesem Fall nur das Resultat der InterBase-Fehlernummer, so das es im Prinzip egal ist, welche dieser Fehlernummern ausgewertet wird. Allerdings gibt es auch "verschachtelte" BDE-Fehlermeldungen (die aus mehreren Fehlernummer-Einträgen bestehen), und hier ist der NativeError-Wert eindeutiger. Das ist aber eine Frage des eigenen Geschmacks
Comment