Tom2 (der authentifizierte): Fehlerbehandlung

Hi Leute

Ich hab mal ein paar Fragen zum Thema Fehlerbehandlung, genauer wie man mit eher nicht zu erwartenden Fehlern umgeht.

Ich arbeite an einer Webapplikation (VBScript/ASP) mit einer Datenbank im Hintergrund (MS SQL Server). Nun bin ich dabei Daten aus der DB auszulesen und in eine Datei zu schreiben. Ich hab einen ganzen Haufen verlinkter Tabellen, wobei die Fremdschlüssel eigentlich stimmen müssten. Was mache ich aber, wenn unerwarteterweise ein Fremdschlüssel nicht vorhanden ist (NULL in einem Feld, welches nicht NULL sein dürfte)? Oder was wenn ein Fremdschlüssel ungültig ist, d.h. in der referenzierten Tabelle besteht kein Datensatz mit dem entsprechenden Primärschlüssel?

Zuerst wollte ich die Daten auf ihre Richtigkeit hin prüfen, bevor ich sie weiter verwende. Jedoch scheint mir das unnötiger Aufwand da _eigentlich_ das RDBMS für die referenzielle Integrität zuständig ist und das auch in 99.87% aller Fälle klappt. Momentan prüfe ich, ob die Daten nicht gülltig sind - und wenn dem so ist verlasse ich die Funktion sofort und ohne wenn und aber. Natürlich räume ich die zuvor instanzierten Objekte ab und erkenne den Fehler daran, dass kein Output vorhanden ist.

Wie geht ihr mit solchen und ähnlichen eher nicht zu erwartenden Fehlern um? Was sagen eure Coding Standards dazu?

Gruss

Tom2

  1. Hallo,

    Wie geht ihr mit solchen und ähnlichen eher nicht zu erwartenden Fehlern um?

    Von vornherein verhindern [1] und mittels Unit Tests nachprüfen.

    [1]

    • Wenn du eine Fremdschlüsselspalte als NOT NULL definierst, weil sie laut reiflicher Überlegung während der Designphase nicht NULL sein darf, dann kann sie auch nie einen NULL-Wert annehmen

    • Wenn du für eine Fremdschlüssel-Beziehung "Referentielle Integrität" einschaltest, vorausgesetzt dein RDBMS kennt sowas, können keine Karteileichen entstehen: Entweder kannst du den Kind-Datensatz nicht ändern/löschen/hinzufügen oder eine DML Aktion auf dem Eltern-Datensatz kaskadierend auf dessen über Fremdschlüssel abhängige Kind-Datensätze aus (ON DELETE CASCADE usw.)

    • Wenn du spätere Änderungen an Fremdschlüssel-Beziehungen vornimmst, bist du selbst verantwortlich ob beim Anlegen der Beziehungen bestehende Daten überprüft werden.

    Ciao, Frank

    1. Hallo Frank

      Wie geht ihr mit solchen und ähnlichen eher nicht zu erwartenden Fehlern um?

      Von vornherein verhindern [1] und mittels Unit Tests nachprüfen.

      Mir ist schon klar, das solche Fehler normalerweise durch das DBMS gehandelt werden. Meine Praxiserfahrung zeigt jedoch, dass sie trotzdem auftreten können (wobei ich menschliches Versagen nicht ausschliessen möchte).
      Du sagst also, dass du solche Eventualitäten einfach ignorierst? Naja, das tue ich mit meiner jetztigen Lösung im Prinzip ja auch (leerer Output), ich versuche jedoch einen Server-Error (ASP) zu umgehen.

      Peace

      Tom2

      1. Hi,

        wie du sagst, es kann durchaus auch an menschlichem Versagen hängen ...

        Dass ich auftretende Fehler ignoriere, habe ich so nicht gesagt. Ich habe gerade selber mit einer Datenmigration zu tun, die regelmäßig seltsame Zustände hervorbriugt, weil dem Benutzer erlaubt war eindeutige Werte doppelt zu vergeben usw. Ist in dem Sinne auch menschl. Versagen.

        Wenn du einen möglichen Server Error manuell umgehst, Abprüfungen, sauberes Verlassen von Routinen usw. dann hast du ja auch eine Art Fehlerbehandlung. Vielleicht solltest du bei solch einem Ereignis irgendwas oder irgendwen in Kenntnis setzen (log schreiben, mail schicken, was auch immer)

        Mein Hinweis, es von vornherein sauber zu halten basierte auf der Annahme, dass du selber ein System bastelst und über deine eigenen Steine oder Beine stolperst, weil am Anfang zu wenig Denkarbeit eingesetzt worden ist.

        Und eben ein DBMS kann Integritätsprobleme auch nur dann selbständig verhindern oder lösen wenn es dazu entsprechend eingerichtet wurde. :)

        Ciao, Frank

  2. Hi Tom2,

    eine gute Möglichkeit, einen "no data found" error zu umgehen ist z.B.

    select count(1) into i from dual where exists (select spalte from tabelle where spalte is null);

    if i=0 then
      select spalte from tabelle where spalte is not null;
    else
      mach_nix();
    end if;

    Wenn also Spalte mindestens einmal null ist, steht in der Variable i der Wert 1 drin. Falls i=0 dann kannst Du ohne Probleme auf die Spalte zugreifen.

    Gruß

    Hans

    1. Hallo,

      Hi Tom2,

      eine gute Möglichkeit, einen "no data found" error zu umgehen ist z.B.

      select count(1) into i from dual where exists (select spalte from tabelle where spalte is null);

      if i=0 then
        select spalte from tabelle where spalte is not null;
      else
        mach_nix();
      end if;

      Wenn also Spalte mindestens einmal null ist, steht in der Variable i der Wert 1 drin. Falls i=0 dann kannst Du ohne Probleme auf die Spalte zugreifen.

      Performancemäßig aber möglicherweise ein Tiefschlag, da jede Abfrage doppelt ausgeführt wird. Bei Abfrage auf IS NULL ohne Verwendung eines Index mit einem FULL TABLE SCAN. Da lasse ich mir lieber einen "no data found" geben und behandle den entsprechend.

      Grüße
      Marcus

      --
      si vis pacem, para iustitiam