Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IBDataset und Autoincrement

8 views
Skip to first unread message

Alfred Gemsa

unread,
Dec 17, 2012, 2:08:25 AM12/17/12
to
Hallo,

in einer Tabelle gibt's ein Feld ID, dass über einen Generator und ein
Before_Insert-Trigger hochgezählt werden soll.

Das IBDataset hat diesbezüglich eine Eigenschaft "GeneratorField", die
auf den Generator, den Feldnamen und "Anwenden bei neuem Datensatz"
gesetzt ist.

Dummerweise zählt ID aber jeweils um Zwei hoch, wenn ich mittels
Dataset.Append einen Record dranhänge.

Was mache ich falsch?

Alfred.

Achim Kalwa

unread,
Dec 17, 2012, 7:09:05 AM12/17/12
to
Hallo,
Ich kenne zwar IBDataset nicht im Detail, aber das sieht mir so aus als
würde IBDataset sich selber um die Vergabe einer neuen ID kümmern. Dabei
wird der Generator zum ersten Mal inkrementiert. Dein Trigger macht dann
das gleiche noch einmal.

Zeig' doch mal den Code vom Trigger.
Evtl. kannst Du den so umbauen, dass der nur dann Generator angesprochen
wird, wenn ID noch keinen Wert hat:

create trigger TBI_KUNDE for KUNDE before insert
position 0 as
begin
if (new.ID IS NULL) then new.ID = GEN_ID(G_ID, 1);
end

(G_ID ist der Generator)

HTH
Achim

Alfred Gemsa

unread,
Dec 17, 2012, 7:32:38 AM12/17/12
to
Am 17.12.2012 13:09, schrieb Achim Kalwa:

> Ich kenne zwar IBDataset nicht im Detail, aber das sieht mir so aus als
> würde IBDataset sich selber um die Vergabe einer neuen ID kümmern. Dabei
> wird der Generator zum ersten Mal inkrementiert. Dein Trigger macht dann
> das gleiche noch einmal.
>
> Zeig' doch mal den Code vom Trigger.
> Evtl. kannst Du den so umbauen, dass der nur dann Generator angesprochen
> wird, wenn ID noch keinen Wert hat:
>
> create trigger TBI_KUNDE for KUNDE before insert
> position 0 as
> begin
> if (new.ID IS NULL) then new.ID = GEN_ID(G_ID, 1);
> end

IBExpert zeigt mir folgendes:

/******************************************************************************/

/**** Generated by IBExpert 17.12.2012 07:15:05
****/
/******************************************************************************/


SET SQL DIALECT 3;

SET NAMES NONE;

CREATE TABLE NEW_TABLE (
ID INTEGER NOT NULL,
NAME CHAR(10)
);

ALTER TABLE NEW_TABLE ADD CONSTRAINT PK_NEW_TABLE PRIMARY KEY (ID);

CREATE GENERATOR GEN_NEW_TABLE_ID;

SET TERM ^ ;

/* Trigger: NEW_TABLE_BI */
CREATE TRIGGER NEW_TABLE_BI FOR NEW_TABLE
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_NEW_TABLE_ID,1);
END
^

SET TERM ; ^


Das sieht nicht so verkehrt aus.

Alfred.

Achim Kalwa

unread,
Dec 17, 2012, 2:28:04 PM12/17/12
to
Moin,

Alfred Gemsa wrote:

> CREATE TRIGGER NEW_TABLE_BI FOR NEW_TABLE
> ACTIVE BEFORE INSERT POSITION 0
> AS
> BEGIN
> IF (NEW.ID IS NULL) THEN
> NEW.ID = GEN_ID(GEN_NEW_TABLE_ID,1);
> END

Ja, das sieht gut aus. Und vermutlich funktioniert es prima, wenn Du per
IBExpert oder einem anderen SQL-Tool Daten in die Tabelle schreibst:

insert into NEW_TABLE(NAME) values ('TEST');

Dabei sollte der Trigger ausgelöst werden und das hier fehlenden Feld
"ID" befüllen. Dabei wird Generator immer nur um 1 erhöht.

Jetzt zurück zu IBDataset. Wenn dort nach einer vergleichbaren Aktion
der Generator um 2 erhöht ist, dann bekommt IBDatabase nix davon mit,
dass da im Hintergrund noch ein Trigger aktiv ist, der ebenfalls eine ID
erzeugt.

Also entweder
a)
auf den Trigger verzichten und nie niemals nicht Daten von Hand per SQL
eingeben...

b)
im IBDataset die Generator-Option wieder abschalten; der Trigger kümmert
sich um die Vergabe einer ID.

Vermutlich willst Du aber *nach* dem .Post die ID des neuen Datensatzes
kennen. Dann bleibt Dir nichts anderes übrig, als *vor* dem .Post selber
den Generator abzufragen und die gelieferte ID in das IBDataset zu
schreiben (OnNewRecord).

HTH
Achim




Alfred Gemsa

unread,
Dec 17, 2012, 3:31:02 PM12/17/12
to
Am 17.12.2012 20:28, schrieb Achim Kalwa:

> Also entweder
> a)
> auf den Trigger verzichten und nie niemals nicht Daten von Hand per SQL
> eingeben...
>
> b)
> im IBDataset die Generator-Option wieder abschalten; der Trigger kümmert
> sich um die Vergabe einer ID.

b) ist richtig!

Wozu hat das aber IBDataset die Generator-Eigenschaft?

> Vermutlich willst Du aber *nach* dem .Post die ID des neuen Datensatzes
> kennen. Dann bleibt Dir nichts anderes übrig, als *vor* dem .Post selber
> den Generator abzufragen und die gelieferte ID in das IBDataset zu
> schreiben (OnNewRecord).

Das verstehe ich nicht: Beim "Append" trage ich Daten nur in die übrigen
Felder ein, das Insert-SQL des IBDatasets lautet (ich habe neben ID nur
noch das Feld NAME):

"insert into TB1 (NAME) values (:NAME)"

Nach dem Post sind dann alle IDs selbständig gefüllt, und ich kann sie
ganz einfach abfragen.

Danke,

Alfred

Martin Behrens

unread,
Dec 18, 2012, 3:24:58 PM12/18/12
to
Am 17.12.12 21:31, schrieb Alfred Gemsa:

> Am 17.12.2012 20:28, schrieb Achim Kalwa:
>
>> Also entweder
>> a)
>> auf den Trigger verzichten und nie niemals nicht Daten von Hand per SQL
>> eingeben...
>>
>> b)
>> im IBDataset die Generator-Option wieder abschalten; der Trigger kümmert
>> sich um die Vergabe einer ID.
>
> b) ist richtig!

Das kommt darauf an, wo man diese Logik platziert.

> Wozu hat das aber IBDataset die Generator-Eigenschaft?

Damit man keinen Trigger dafür braucht.

>> Vermutlich willst Du aber *nach* dem .Post die ID des neuen Datensatzes
>> kennen. Dann bleibt Dir nichts anderes übrig, als *vor* dem .Post selber
>> den Generator abzufragen und die gelieferte ID in das IBDataset zu
>> schreiben (OnNewRecord).
>
> Das verstehe ich nicht: Beim "Append" trage ich Daten nur in die übrigen
> Felder ein, das Insert-SQL des IBDatasets lautet (ich habe neben ID nur
> noch das Feld NAME):
>
> "insert into TB1 (NAME) values (:NAME)"
>
> Nach dem Post sind dann alle IDs selbständig gefüllt, und ich kann sie
> ganz einfach abfragen.

Das einfache Abfragen dürfte dann spätestens beim Multiuserbetrieb zum
Problem werden.
Die ID zu bestimmen kann dann schon ein erhebliches Problem darstellen.

Ich bin der Meinung, dass man sich für die Durchsetzungs solcher Regeln
(ID Vergabe) auf einen Weg festlegen muss: Entweder setzt man es auf
Datenbankebene durch oder auf Applikationsebene durch. Beides hat Vor-
und Nachteile.


Martin

0 new messages