Announcement

Collapse
No announcement yet.

Interbase: autoinc. Felder

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

  • Interbase: autoinc. Felder

    Hallo<p>
    Ich habe eine Tabelle mit der Spalte NUMMER: INTEGER (Primärindex). Wenn vom User ein Datensatz gelöscht werden soll,<br>
    wird die Spalte DELETED auf 1 gesetz. Im Delphiprogramm holt die Query-Komponente mit<br>
    SQL.TEXT:='select * from tabelle where (DELETED IS NULL) or (DELETED<>1) order by nummer';<br>
    die Daten auf den Bildschirm.<br>
    Damit wird der "gelöschte" Datensatz für die Query unsichtbar.<br>
    Es gibt einen insert before trigger in der Tabelle, der mit new.nummer=gen_id(nummergenerator,1)<br>
    einen neuen Datensatz mit einer neuen Nummer erzeugt.<br>
    Ich möchte allerdings, dass beim Einfügen eines Datensatz zuerst gesucht wird,<br>
    ob ein Datensatz gelöscht wurde (DELETED=1) und dann dieser mit den Daten überschrieben wird.<br>
    So enthält jede fortlaufende Nummer einen verwendeten Datensatz.<p>
    Ich habe dazu diesen before insert trigger geschrieben:<br>
    <br>
    declare variable num integer;<br>
    begin<br>
    select min(num)<br>
    from tabelle<br>
    where deleted=1<br>
    into :num;<br>
    if num>=1 then<br>
    new.nummer=num<br>
    else<br>
    new.nummer=gen_id(nummergenerator,1);<br>
    <br>
    Doch das funktioniert nicht, wie geplant.<br>
    Wer kann mir weiterhelfen, gibt es einen anderen Weg ?<p>
    Gruß Marcus

  • #2
    Hi,

    a)
    Wenn der before insert Trigger angesprochen wird, läuft der Insert-Vorgang auf dem Server bereits und es wird -sofern es zu keiner Integritätsverletzung kommt- immer ein neuer DS erzeugt. Wenn dir also in deinem before-insert Trigger "einfällt", dass du eigentlich gar keinen neuen Satz anlegen möchtest, sondern einen alten, "gelöschten" Satz reaktivieren willst, musst du in dem Trigger eine Exception auslösen, damit der Schreibvorgang abgebrochen wird. Im Normalfall arbeitet IB beim Schreiben folgende fünf Schritte ab:

    - before trigger auslösen<p>
    - Constraints prüfen<p>
    - Daten schreiben<p>
    - Indizes aktualisieren<p>
    - after trigger auslösen<p>

    b)
    Wo liegt der tiefere Sinn, alte PK's wieder zu verwenden ?? Vergib doch einfach immer einen Neuen. Deine "gelöschten" Datensätze löschst du mittels "DELETE FROM TABELLEXY WHERE DELETED=1"

    Gruß
    Gesin

    Comment


    • #3
      hallo Gesine,<p>
      vielen Dank für die Tips. Ich bin halt ordnungsliebend und dachte, man sollte die gelöschten Zahlen nicht "verschwenden".<br>
      Ich bin Hobbyprogrammierer und weiss nicht, ob die Profis das nicht auch so machen.<br>
      Jedenfalls, wenn ich im Trigger immer nur eine neue PK erzeuge, spare ich mir jede Menge Verwaltungsaufwand und komme schneller voran.<p>
      Gruß Marcu

      Comment


      • #4
        Hallo Marcus,

        Aber es gibt doch reichlich Zahlen und sie kosten nix und fortlaufend sind sie immer ;-)

        Gruß Gesine

        P.S.

        Genau, denn recycelst du PK's, bedeutet das erheblichen Mehraufwand in deiner Anwendung. Denke z.B. an Detailsätze, die beim recyceln immer <b>zeitnah</b> mit "gelöscht" bzw. markiert werden <b>müssen</b> ( sonst 'erbt' der 'neue' Satz evtl. die alten Detailsätze -Stichwort: Kaskadiertes Löschen, Referenzielle Integrität- ). Bei Einmalnutzung von PK's könntest du z.B. nachts ( wenn dein Server nicht so unter Last steht ) eine Anwendung in deiner DB nach verwaisten Detailsätzen suchen lassen und diese dann erst entfernen, da du dir sicher sein kannst, dass kein neuer Satz diese Detailsätze zwischenzeitlich zu Gesicht bekommt

        Comment

        Working...
        X