Announcement

Collapse
No announcement yet.

DBException identifizieren

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

  • DBException identifizieren

    Hi!

    Wichtige Stellen in einem Programm werden u.a. mit „try ... except...end“ Blöcken abgesichert, z.B. etwa so:
    <PRE>try
    MSQuery1.SQL.Clear;
    MSQuery1.SQL.Add('create database testdb');
    MSQuery1.Execute;
    except
    on e: EDataBaseError do
    begin
    MessageDlg(e.Message, mtError, [mbOK], 0);
    end;
    end;
    </PRE>
    Hier wird versucht auf einem MS-SQL-Server (MSDEA) eine Datenbank zu erstellen. Falls irgend eine DB-Exception ausgelöst wird, dann wird eine Meldung auf dem Bildschirm angezeigt. In der kann z.B. so etwas stehen: „Datenbank testdb existiert schon“. Auf diese Meldung kann der Benutzer nun reagieren (im obigen Fall kann er lediglich die Exception zur Kenntnis nehmen).

    So weit so gut. Nun möchte ich einige DB-Exceptions per Programm abhandeln. Damit ich die Exceptions erkennen und entsprechend reagieren kann, muss ich den eindeutigen Errorcode kennen (z.B. „Datenbank existiert schon“ = Errorcode: 123456).

    Meine Frage:<BR>
    Wie kann ich den eindeutigen Errorcode von MS-SQL-Server (MSDEA) der ausgelösten Exception rausfinden?

    Viele Grüße<BR>
    Markus

  • #2
    Hallo,

    dazu kann die <b>Errors</b>-Kollektion des Connection-Objekts (alias TADOConnection) ausgelesen werden. Am einfachsten geht das in einer normalen Anwendung über eine Ereignisbehandlungsmethode für <b>OnPostError</b>:
    <pre><b>procedure</b> TForm1.ADODataSet1PostError(DataSet: TDataSet; E: EDatabaseError;
    <b>var</b> Action: TDataAction);
    <b>var</b>
    i : Integer;
    s : <b>String</b>;
    <b>begin</b>
    <b>if</b> E <b>is</b> EADOError <b>then</b>
    <b>with</b> E <b>as</b> EADOError <b>do</b>
    MemoLog.Lines.Add(e.Message);
    <b>with</b> ADOConnection1 <b>do</b>
    <b>for</b> i:= 0 <b>to</b> Errors.Count - 1 <b>do</b>
    <b>begin</b>
    s := Format(<font color="#9933CC">'Source: %s'</font>, [Errors[i].Source]);
    MemoLog.Lines.Add(s);
    s := Format(<font color="#9933CC">'NativeError: %d'</font>, [Errors[i].NativeError]);
    MemoLog.Lines.Add(s);
    s := Format(<font color="#9933CC">'%s; (SQLState: %s)'</font>,
    [Errors[i].Description, Errors[i].SQLState]);
    MemoLog.Lines.Add(s);
    MemoLog.Lines.Add(<font color="#9933CC">' --- '</font>);
    <b>end</b>;
    Action := daAbort;
    <b>end</b>;</pre>
    Über die Eigenschaf <b>NativeError</b> des Fehlereintrags in der Errors-Kollektion kann die originale MS SQL Server-Fehlernummer ausgelesen werden. Bei DDL-Anweisungen, die über die TADOConnection-Methode <b>Execute</b> direkt ausgeführt werden, kann die Errors-Kollektion direkt abgefragt werden

    Comment


    • #3
      Moin Andreas (oder vielleicht besser „Guten Tag Herr Kosch“?)!

      Vielen Dank für Deinen/Ihren Hinweis, der mir sehr geholfen hat.

      Allerdings habe ich noch eine Frage, die ich zuerst mit ein paar Worten erklären möchte. Mein Vorhaben ist bei jedem Start des Programms sicherzustellen, dass alle benötigten Datenbanken und Tabellen vorhanden sind.

      Deswegen:
      <PRE> A. Verhalten 1:
      -prüfen (mit z.B. Show Tables, Show Databases usw...) ob Datenbank und alle benötigten Tabellen existieren.
      -wenn alles geprüft ist und es nötig ist die Datenbank und Tabellen mit „create“ erstellen
      -eventuelle Exceptions abfangen und reagieren
      B. Verhalten 2:
      -keine Prüfungen machen , sondern sofort versuchen die Datenbank und benötigten Tabellen zu erstellen
      -eventuelle Exceptions abfangen und entsprechend reagieren<PRE>

      Ist Verhalten „A“ ein besserer Programmierungs-Stil als Verhalten „B“ ?<BR>Ich würde gerne Deine/Ihre Meinung dazu wissen.<PRE>

      Viele Grüße
      Marku

      Comment


      • #4
        Hallo,

        das Verhalten "B" ist der übliche Weg, denn in diesem Fall reicht es aus, wenn das Anwendungsprogramm (die Datenbank-Session) nur mit Zugriffsrechten auf die eigene Datenbank ausgestattet wird.

        Um das Verhalten "A" umsetzen zu können, wird eine Datenbank-Verbindung mit sehr hohen Rechten benötigt.

        Im besonderen Fall der MSDE (in der Bedeutung einer lokalen Datenbank) wäre aber auch das Verhalten "A" tolerierbar

        Comment

        Working...
        X