Announcement

Collapse
No announcement yet.

Indexfehler in OnUpdateError abfangen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Indexfehler in OnUpdateError abfangen

    Hallo,

    wer weiß, wie ich eine Bedingung formulieren muß, dort um einen Indexfehler abzufangen?

    Danke Kai!

  • #2
    Hallo,

    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&gt

    Comment


    • #3
      Hallo Andreas,

      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?!

      Gruß Kai

      Comment


      • #4
        Hallo,

        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

        Working...
        X