Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi generator richtig verwenden (https://www.delphipraxis.net/19757-generator-richtig-verwenden.html)

Nightfly 8. Apr 2004 12:01


generator richtig verwenden
 
Hier das Insert Statement meiner DataSet komponente:
SQL-Code:
INSERT INTO RECHNUNG(STELLE,
    BEREICH,
    R_NUMMER,
    R_STELLER,
    R_DATUM,
    R_ARTIKEL,
    R_ANZ,
    R_EPREIS,
    R_MWST,
    LFDNR
)
VALUES(:STELLE,
    :BEREICH,
    :R_NUMMER,
    :R_STELLER,
    :R_DATUM,
    :R_ARTIKEL,
    :R_ANZ,
    :R_EPREIS,
    :R_MWST,
    GEN_ID(gen_rechnung,1)

)
wenn ich aber den Button klicke, der DataSet.Post ausführt,meint er validation verletzung, weil das feld lfdnr null sein soll.
In meiner Datenbak existier aber folgender generator:
SQL-Code:
CREATE GENERATOR GEN_RECHNUNG;
SET GENERATOR GEN_RECHNUNG TO 1;
Wird der nicht richtig ausgeführt? stimmt mein insert statement nicht?

Hansa 8. Apr 2004 12:15

Re: generator richtig verwenden
 
Ein Generator macht IMHO nur richtig Sinn mit einem Trigger. Dies hieße bei dir : Lege in der DB einen Before Insert Trigger an. Dann wird die Nr. ohne Dein zutun aus dem Generator genommen. Diesen kannst du in einem Abwasch dann gleich um 1 erhöhen.

Nightfly 8. Apr 2004 12:24

Re: generator richtig verwenden
 
hab auch schon an einem trigger überlegt,aber keine idee wie der aussehen soll. Kannst du mir da vlt. helfen?

und oben genanntes Beispiel sollte doch funktionieren, das Insert SQL ruft doch auch den generator aus,der dadurch eine nummer zurückgibt und dich selbst um 1 erhöht

Lemmy 8. Apr 2004 12:32

Re: generator richtig verwenden
 
Hi Nightfly,

Du verwendest doch die IBX-Komponeten? Dann kannst Du über die Eigneschaft "GeneratorField" der IBDataSet den Generator ansprechen. Die Lösung über einen Trigger finde ich nicht gut, denn Du kannst dann im Client nur auf Umwegen auf die ID des eben erzeugten Datensatzes zugreifen.

Grüße
Lemmy

Nightfly 8. Apr 2004 12:47

Re: generator richtig verwenden
 
Nein, ich verwende die FibPlus Komponenten. Einzig unter AutoUpdateOptions hab ich sowas wie GeneratorName gefunden. Aber auch wenn ich da den generator einstelle,Key fields auf LFDNR setze,die tabelle auf rechnung...der fehler bleibt :-(

Robert_G 8. Apr 2004 13:20

Re: generator richtig verwenden
 
Also ich würde hier auch dringend zu einem Trigger raten.
Ist der Trigger einmal an der Tabelle musst du dir keine Sorgen mehr machen, ob der PK eindeutig ist. Egal wie auf die Tabelle zugegriffen wird.
Zu dem von Lemmy angesprochenen Problem:
Gibts es in IB sowas wie die Returning Clause?
SQL-Code:
Insert INTO RECHNUNG
  (STELLE
  ,BEREICH
  ,R_NUMMER
  ,R_STELLER
  ,R_DATUM
  ,R_ARTIKEL
  ,R_ANZ
  ,R_EPREIS
  ,R_MWST)
VALUES
  (:STELLE
  ,:BEREICH
  ,:R_NUMMER
  ,:R_STELLER
  ,:R_DATUM
  ,:R_ARTIKEL
  ,:R_ANZ
  ,:R_EPREIS
  ,:R_MWST)
Returning LfdNr INTO :o_LfdNr
o_LfdNr müsste dann als Ouput Parameter eingestellt sein und enthält nach dem Insert die neue ID.

Lemmy 8. Apr 2004 13:35

Re: generator richtig verwenden
 
Zitat:

Zitat von Robert_G

Zu dem von Lemmy angesprochenen Problem:
Gibts es in IB sowas wie die Returning Clause?

Nein, mir nicht bekannt, wäre aber ne sinnvolle Erweiterung....

@NightFly: Leider habe ich die FIBPlus vor zwei Tagen vom Rechner geworfen. Aber da sollte eigentlich Hansa weiterhelfen können....

Grüße
Lemmy

Nightfly 8. Apr 2004 13:41

Re: generator richtig verwenden
 
na da hoff ich der schaut hier mal rein :)

@Robert_G sorry, dein Code sagt mir nun wieder garnix. Das kann doch nicht die Insert Anweisung sein die in mein DataSet soll,oder Denn darin ist ja mit keiner Silbe der generator erwähnt,och hab ich bloß ne lange leitung? Bitte um hilfe!

Robert_G 8. Apr 2004 14:03

Re: generator richtig verwenden
 
Zitat:

Das kann doch nicht die Insert Anweisung sein die in mein DataSet soll,oder Denn darin ist ja mit keiner Silbe der generator erwähnt,och hab ich bloß ne lange leitung?
Jupp :mrgreen:
Bei dem Statement ging ich davon aus, dass ein Trigger an der Tabelle hängt...

Aber wenn Lemmy sagt es gibt keine Returning Cluse in IB, dann gibt's die auch nicht.

Pech gehabt... :tongue:

DelphiDeveloper 8. Apr 2004 18:56

Re: generator richtig verwenden
 
ich arbeite zwar mit IBObjects und nicht mit FIBPlus aber wenn ich mich recht entsinne
gibt es bei FIB bei den AutoUpdateOptions nicht nur GenName und GenStep sondern noch
auch noch WhenGetGenId da kann man dann einstellen nie, beforepost usw.

Hansa 8. Apr 2004 20:45

Re: generator richtig verwenden
 
Bei mir gibts (zumindest vorerst) nur Generator + Trigger. 8) Alles andere wird unnötig zu kompliziert. @Lemmy: ich weiß von Deinen SPs, aber den Sinn sehe ich nicht recht ein. :P Die Tabelle wird angelegt und dann wird Generator/Trigger definiert im IBExpert und basta. Für jede Tabelle fast derselbe als BI-Trigger. Z.B. so :
SQL-Code:
/* Trigger: TABLE8_BI0 */
CREATE TRIGGER TABLE8_BI0 FOR TABLE8
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID (GEN_TABLE8_ID,1);
end
^
Die Spezialitäten bei FIBplus liegen eher im Mehrplatzbetrieb. Bei einigen Tabellen steht WhenGetID im DataSet auf OnNewRecord und der Generatorname ist angegeben, bei anderen nicht. Sieht fast so aus, als ob es egal wäre. Auf jeden Fall geht es momentan immer problemlos.

DelphiDeveloper 8. Apr 2004 21:01

Re: generator richtig verwenden
 
Zitat:

Die Lösung über einen Trigger finde ich nicht gut, denn Du kannst dann im Client nur auf Umwegen auf die ID des eben erzeugten Datensatzes zugreifen.
Das hat schon seine Daseinsberechtigung. Denke bspw. an Master/Detail Relationen

Szenario: Rechkopf + Rechpositionen

Rechpositionen brauchen ID vom Rechkopf. Wenn du den Rechkopf postest weist du aber nicht was dein trigger fuer ne ID vergeben hat. Und somit mußt du die ID des Rechkopfes erst ermitteln um sie anschschließend in den Rechpositionen einzutragen.

Robert_G 8. Apr 2004 21:18

Re: generator richtig verwenden
 
Gibt es in IB ein Äquvalent zu den Package-variablen in Oracle? Also eine Variable, deren Wert sich nur in der UGA befindet.
Keine Session kann den Wert einer anderen überschreiben.
Dadurch könnte man unabhängig von parallen Transaktionen anderer Sessions herausfinden, welche ID der neue DS hat.
Eine IMHO eklige Lösung, aber vielleicht funktioniert es. Wenn nicht, dann warte bis IB oder FB ein Gegenstück zu RETURNING hat. :wink:
SQL-Code:
CREATE TRIGGER TABLE8_BI0 FOR TABLE8
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID (GEN_TABLE8_ID,1);

  Shema.Package.Variable := New.ID;
end
OT:
@Hansa
Übrigens,du verhinderst nicht, dass der User beim Öffnen der Tabelle mit einem anderen Programm irgendeinen Mist reinschreibt.
Bei einem INSERT sollte also immer die PK aus der Sequence beschrieben werden:
SQL-Code:
CREATE TRIGGER TABLE8_BI0 FOR TABLE8
ACTIVE BEFORE INSERT POSITION 0
AS
begin
    NEW.ID = GEN_ID (GEN_TABLE8_ID,1);
end

Hansa 8. Apr 2004 21:23

Re: generator richtig verwenden
 
Für so was gibt es auch Before Update Trigger. Aber ich denke mal, zuerst soll hier das konkrete Problem gelöst werden.

Lemmy 9. Apr 2004 07:18

Re: generator richtig verwenden
 
Hi,


Zitat:

Zitat von Robert_G
Aber wenn Lemmy sagt es gibt keine Returning Cluse in IB, dann gibt's die auch nicht.

hoffentlich habe ich auch nichts überlesen.... *ggg*

@hansa: Wie willst denn Du an die ID des eben gespeicherten Datensatzes kommen? Da gibt es imho nur 3 Möglichkeiten:

1. Über ne Eigenschaft der Komponente (GeneratorField,...)
2. Über ne Stored Procedure (eine die den Insert erledigt)
3. Direkte Abfrage des Generators

Andere Möglichkeiten gibts nicht! Nur bei bestimmten Tabellen wenn es noch weitere eindeutige Spalten in der Tabelle gibt, kannst Du nach dem Insert die ID mit ner Abfrage holen, aber wie oft kommt das vor?

@Robert: Was ist die UGA? Mir ist aber auch nichts bekannt, dass es "globale" Variablen gibt.

Grüße
Lemmy

Hansa 9. Apr 2004 13:06

Re: generator richtig verwenden
 
Zitat:

Zitat von Lemmy
@hansa: Wie willst denn Du an die ID des eben gespeicherten Datensatzes kommen?

ich habe hier eine Tabelle mit 6000 Einträgen. Die habe ich gelöscht und sie dann wieder mit den 6000 Einträge neu gefüllt. Die IDs, die ich jetzt habe sind von 6001 bis 12000 Den Generatorwert habe ich in Ruhe gelassen. Die IDs kommen vom Trigger. Das Programm braucht ca. 1 Min. und die IDs sind durchnummeriert. Geht ohne Probleme. Was brauche ich denn sonst noch ? :gruebel:

Robert_G 9. Apr 2004 14:16

Re: generator richtig verwenden
 
UGA = User Global Area
SGA = Shared Global Area
Package variablen in Oracle legen ihre Werte in der UGA ab, also kann die Variable für jede Session einen anderen Wert haben.
Deshalb meine Frage, ob es ein Gegenstück davon in IB gibt.
@Hansa
Ein Trigger, der bei BEFORE UPDATE feuert, sollte eigentlich nur die :New.PK auf :Old.PK setzen.
Ein Trigger, der die PK erzeugt sollte immer eine PK aus der Sequence (Generator oder wie das auch immer in IB heißt ;) ) ziehen. Nicht nur bei :New.PK is null .

Lemmy 9. Apr 2004 15:23

Re: generator richtig verwenden
 
Zitat:

Zitat von Hansa
Geht ohne Probleme. Was brauche ich denn sonst noch ? :gruebel:

Bei Masseninserts ist das ja auch egal, was machst Du aber bei folgendem:

Du legst ne neue Adresse an. Diese wird in der DB gespeichert. Jetzt musst Du aber noch in weiteren Referenztabellen Einträge mit der ID der Adresse einfügen! Oder was machst Du, wenn der User den eben eingefügten Datensatz in der Detailansicht sehen will. Dazu brauchst Du immer die ID der eben eingefügten Daten.

Grüße
Lemmy

Hansa 9. Apr 2004 19:13

Re: generator richtig verwenden
 
Wenn das bei 100 Records pro Sek. funktioniert, ja Kruzifix, wo liegt denn da der Haken ? Ich habe jetzt folgendes gemacht : 1. neuen Artikel angelegt. 2. neue Warengruppe und diese gespeichert. 3. dem neuen Artikel diese Warengruppe (also die ID der Warengruppe) zugeordnet und gespeichert. Programm beendet und neu gestartet. Alles war wie gewollt. 8)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz