Announcement

Collapse
No announcement yet.

Generator-Problem

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

  • Generator-Problem

    hallo, allerseits und ein Frohes Neues Jahr.

    Folgender Code

    Select gen_id(GEN_IDNR_PROGTEILE,0) as IRGENDWAS from PROGTEILE;

    liefert bei mir 75 Ergebnisse mit gleichem Inhalt, wenn ich diese Abfrage z.B. mit ibexpert direkt stelle. Ich benutze diese Abfrage regelmäßig um nach dem insert die Datensatz-ID zu bekommen.

    Stelle ich die Abfrage

    Select gen_id(GEN_IDNR_PROGTEILE,<B>1</B>) as IRGENDWAS from PROGTEILE;

    werden 75 Ergebnisse in aufsteigender Reihenfolge geliefert, also am ende ist mein generatorstand nicht n + 1, sondern n + 75. Gut, diese version würde man ja nicht laufenlassen, aber

    Wie kommen diese mengen zustande?

    Gruß

    Bernhard

    ... in diesem falle: Fragen sie nicht ihren Arzt und Apotheker...

  • #2
    Hallo Bernhard,

    <b>Select gen_id(GEN_IDNR_PROGTEILE,0) as IRGENDWAS from RDB$DATABASE</b> stellt sicher das nur ein Datensatz zurückgeliefert wird (weil in dieser Tabelle immer nur ein Datensatz vorhanden ist).

    Unabhängig davon ist dieser Weg bei einem Multi-User-Betrieb extrem unsicher (die Generatoren werden bei IB Transaktionsunabhängig verwaltet, damit halt immer ein eindeutiger Wert erstellt werden kann). Da zwischen Deinem Insert und dem nachfolgenden Select (gen_id...) eine gewisse Zeitspanne dazwischenliegt kann sich der Wert des Generators bereits wieder geändert haben (z.B. wenn ein anderer User einen neuen Datensatz speichert).

    In Deinem Fall ist es besser nicht einem Trigger die Vergabe der ID zu überlassen sondern bevor der Datensatz eingefügt wird holst Du Dir einen neuen Generatorwert ergänzt den neuen Datensatz um diesen Wert und speicherst dann erst diesen Datensatz. Das Ganze kann man in einer StoredProc "verpacken" (was ich persönlich bevorzuge).

    Tschüß

    Torste

    Comment


    • #3
      Vielen Dank für Deine Antwort.

      Vielleicht habe ich mich nicht klar genug ausgedrückt: Mich interessiert, warum es bei einer Abfrage wie o.g. zu einer Ergebnismenge von 75 Tupel kommt, egal ob bei 0 oder 1. Das dies kein Artefakt ist, wird daran erkenntlich, dass der Generatorstand am Ende n + 75 ist.

      Warum kommt es zu einer Menge n > 1

      Comment


      • #4
        Hallo Bernhard,

        Deine Frage hatte ich schon so verstanden, allerdings hatte ich gedacht, dass es reicht die Lösung zu präsentieren und zusätzlich die grundsätzliche Problematik Deiner Vorgehensweise im Multi-User Betrieb aufzuzeigen.

        Ein <b>Select gen_id(...) from testtable</b> wirkt wie ein <b>select * from testtable</b>, d.h. die Funktion gen_id() wird für jeden Datensatz dieser Tabelle (bei meinem Beispiel testtable) separat ausgeführt. Wenn Deine Tabelle 75 Datensätze hat, dann enthält das Ergebnis ebenfalls 75 Datensätze.

        Tschüß

        Torste

        Comment


        • #5
          Erstmal Entschuldigung und Danke für die erneute Antwort.

          Jetzt hab ich's verstanden. Was bin ich doch für ein dummer Mensch. (Schon das zweite Mal in diesem Jahr).

          Könntest Du mir freundlicherweise mal Deine stored procedure zeigen, die das von Dir richtig erkannte grundsätzliche Problem umgeht

          Danke

          Bernhar

          Comment


          • #6
            Hallo Bernhard,

            Du brauchst Dich nicht zu entschuldigen.

            Eine StoredProc könnte z.B. so aussehen:
            <b><pre>
            CREATE PROCEDURE INSERT_ADRESSE (
            PLZ VARCHAR(5),
            ORT VARCHAR(30),
            STR VARCHAR(30),
            NR VARCHAR(7))
            RETURNS (
            ADRESS_ID INTEGER)
            AS
            begin
            adress_id = gen_id(generator_adressen_id, 1);
            insert into adressen (ID, postleitzahl, ort, strasse, hausnummer)
            values (:adress_id, lz, rt, :str, :nr);
            suspend;
            end
            </b></pre>

            Tschüß

            Torste

            Comment


            • #7
              hi Torsten, vielen dank

              zwei fragen noch, um mich völlig zu outen:

              1.) ist das suspend immer erforderlich? ich dachte, dies sei nur für select-Statements. dies hier wäre doch ein executable, oder?

              2.) wie käme ich an das ergebnis, wenn ich "hardcore"-mäßig vorginge und nicht eine ibstoredproc verwenden wollte. (ist nur für mein verständnis). bei execSQL('Execute insert_adress(....') bekäme ich ja kein ergebnis.

              Vielen Dank für Deine Geduld

              Gruß, Bernhar

              Comment


              • #8
                Hallo Bernhard,

                da die StoredProc einen Rückgabewert liefern soll ist ein suspend notwendig. Falls kein Rückgabeparameter in einer StoredProc verwendet wird braucht natürlich auch kein Suspend erfolgen.

                <b>Select adress_ID from insert_adresse(...)</b>

                Tschüß

                Torste

                Comment


                • #9
                  Torsten, herzlichen Dank!

                  Nun habe auch ich es endlich begriffen.

                  Gruß, Bernhard :

                  Comment

                  Working...
                  X