Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Clientdaten und Generator (https://www.delphipraxis.net/20995-clientdaten-und-generator.html)

Quake 26. Apr 2004 15:31


Clientdaten und Generator
 
Hallo,

ich benutze Delphi7 und IB. Nun zu meinem Problem : ich habe 2 Tabellen A,B dabei ist A die übergeordnete, d.h. zu einem Record in A möchte ich mehrere Records in B zuordnen. Dazu habe ich in beiden Tabellen ein Spalte ID und in Tab. B zusätzlich eine Spalte die die ID des dazugehörigen Records in Tab. A enthält.
In Delphi habe ich nun ein TIBDataSet mit Tab. A verknüpft un den Generator Gen_A der Eigenschaft Generatorfield zugewiesen.
Nun mochte ich aber auch die ID in der Tabelle B vom Generator Gen_B erzeugen lassen. Dazu könnte ich auch TIBDataSet verwenden, aber da kann ich die beiden Tabellen nicht miteinander verknüpfen. Nehme ich einen ClientDataSet oder TIBTable kann ich die Tabellen miteinander verknüpfen aber dort gibt es keine Eigenschaft Generator Field.

Nun die Frage an euch : Was tun? :gruebel:

Danke schon im voraus für eure Antworten.

Jens Schumann 26. Apr 2004 15:50

Re: Clientdaten und Generator
 
Hallo Quake,
meine Tabellen haben grundsätzlich alle eine Spalte mit dem Namen ID.
Dies ist immer die erste Spalte und gleichzeitig der Primary Key.
Den Wert für die Spalte ID hole ich mir über einen Generator.
Den Werte hole ich aber erst vom Generator ab, wenn ich des Insert abgesetzt habe.
Dafür verwende ich immer einen Trigger.
Hiermal ein Beispiel für Interbase:
Code:
/* Domain definitions */
CREATE DOMAIN "TINT" AS INTEGER;
CREATE DOMAIN "TSTRING30" AS VARCHAR(30) CHARACTER SET ISO8859_1 COLLATE DE_DE;

/* Table: KONSOTREE, Owner: SYSDBA */

CREATE TABLE "KONSOTREE"
(
  "ID"  INTEGER NOT NULL,
  "PARENTID"  INTEGER NOT NULL,
  "ENTITY"  VARCHAR(15) CHARACTER SET ISO8859_1 COLLATE DE_DE,
  "NODETEXT"  "TSTRING30" COLLATE DE_DE,
  "KIND"  "TINT",
 PRIMARY KEY ("ID")
);
SET TERM ^ ;

CREATE GENERATOR gen_konsotree ^

/* Triggers only will work for SQL triggers */

CREATE TRIGGER "TRG_KONSOTREE_0" FOR "KONSOTREE"
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then new.id=gen_id(gen_konsotree,1);
end
 ^

CREATE TRIGGER "TRG_KONSOTREE_1" FOR "KONSOTREE"
ACTIVE AFTER DELETE POSITION 0
as
begin
  DELETE FROM konsotree WHERE konsotree.parentid=OLD.ID;
end
 ^

COMMIT WORK ^
SET TERM ;^
Der Trigger "TRG_KONSOTREE_0" feuert, bevor der Datensatz eingefügt wird. Interessant ist hier folgende Zeile
Code:
if (new.id is null) then new.id=gen_id(gen_konsotree,1);
Nur wenn die ID nicht mit gegeben wurde, wird der Inhalt für die ID aus dem Generator mit
Code:
gen_id(gen_konsotree,1)
geholt.

Wenn ich den ID Wert benötige, bevor ich den Datensatz hinzufüge hole ich mir den nächsten Generatorwert über eine Storedprocedure:
Code:
COMMIT WORK;
SET AUTODDL OFF;
SET TERM ^ ;

/* Stored procedures */

CREATE PROCEDURE "GET_KONSOTREE"
RETURNS
(
  "NEWID" INTEGER
)
AS
BEGIN EXIT; END ^


ALTER PROCEDURE "GET_KONSOTREE"
RETURNS
(
  "NEWID" INTEGER
)
AS
BEGIN
  NewID = GEN_ID(GEN_KONSOTREE,1);
END
 ^

SET TERM ; ^
COMMIT WORK;
SET AUTODDL ON;
Fazit: Als Lösung schlage ich Dir die Verwendung von Triggern vor.

Folgendes Buch kann ich schwer empfehlen:InterBase-Datenbankentwicklung mit Delphi

Hansa 26. Apr 2004 16:00

Re: Clientdaten und Generator
 
Hierzu habe ich eine Frage :

Zitat:

Zitat von Jens Schumann
Wenn ich den ID Wert benötige, bevor ich den Datensatz hinzufüge hole ich mir den nächsten Generatorwert über eine Storedprocedure

Wozu soll das gut sein, bzw. wann ist das nötig ? Lemmy hat mir gesagt, er würde Stored Procedures für die Erzeugung einer neuen ID benutzen. Ich nehme aber Generator/Trigger und habe noch nichts bemerkt, was nicht geht. 8) Ja, was nun ?

Jens Schumann 26. Apr 2004 18:08

Re: Clientdaten und Generator
 
Zitat:

Zitat von Hansa
Hierzu habe ich eine Frage :

Zitat:

Zitat von Jens Schumann
Wenn ich den ID Wert benötige, bevor ich den Datensatz hinzufüge hole ich mir den nächsten Generatorwert über eine Storedprocedure

Wozu soll das gut sein, bzw. wann ist das nötig ? Lemmy hat mir gesagt, er würde Stored Procedures für die Erzeugung einer neuen ID benutzen. Ich nehme aber Generator/Trigger und habe noch nichts bemerkt, was nicht geht. 8) Ja, was nun ?

Da muss ich etwas ausholen.
Ich habe mir einen Haufen eigene datensensitive Komponenten geschrieben.
Vom Prinzip her arbeiten die Dinger wie ein TClientDataset. Es werden alle Datensätze
in einem Dataset auf dem Client bearbeitet. Auch wenn neue Datensätze hinzugefügt werden,
werden diese erst lokal auf dem Client angelegt. Erst wenn der User meint er möchte die
Änderungen in die Datenbank übernehmen werden alle Änderungen (Insert's, Delete's und Update's)
in die Datenbank geschoben.

Jetzt habe ich mir auch einen datensensitiven Treeview gebastelt. Der Baum wird zufällig genau mit der Tabelle in der Datenbank abgebildet, die ich hier als Beispiel angegeben habe.
Der Baum wird über die Felder ID und ParentID realisiert.
Ein Datensatz mit ID<>0 und ParentID=0 ist im Treeview ein Rooteintrag. Alle Unterknoten haben als
ParentID dessen ID. Wenn die Unterknoten wiederum Unterknoten haben, haben diese Unterknoten als ParentID die ID der Unterknoten des Rootkontens. :freak:
Wenn ich jetzt einen neuen Unterknoten hinzufüge brauche ich die ID des Parentkontens damit ich für den Unterknoten das Feld ParentID füllen kann.

Hansa 26. Apr 2004 18:23

Re: Clientdaten und Generator
 
Das ist doch wohl alles vollkommen klar, so wie Du das machst. :mrgreen: Das geht wohl nicht anders. Wenn ich jetzt aber keine Unterknoten 8) usw. brauche, ws dann ? Z.B. schreibe ich eine Rechnung, die vorher eingegeben und dann abgespeichert wird. Geht das nun mit Generator/Trigger oder nicht (kein DBgrid, sondern Stringgrid). Wie gesagt : Lemmy... :shock:

Quake 27. Apr 2004 06:34

Re: Clientdaten und Generator
 
Erstmal ein allgemeine Frage, ein z.B. CREATE TABLE muss ich doch nicht commiten, oder?

das mit dem Trigger funzt aber nicht in sofern, das es noch ein bissl komplizierter wird es gibt noch eine Untertabelle von B, die Tabbelle C bei der ich die ID des Records aus B benötige. Und bei einem Trigger bekomme ich die ID der Tabelle B nicht zurück.
Ich glaube, ich muss die Tabelle B wohl extra per Code behandeln. Soll heißen für meine Tab. B verwende ich auch ein TIBDataSet.
Dabei kann ich die Eigenschaft GeneratorField setzen und ich filtere dann die Records der Tab. B bei dem AfterScroll Ereignise
der Tab. A. Dann steht mir auch die ID der Tab. B in der Tab. C zur verfügung.

Danke trotzdem für eure Antworten :-D

PS. Oder wenn euch noch was anderes dazu einfällt - her damit... :-D

Quake 27. Apr 2004 07:09

Re: Clientdaten und Generator
 
Oder kann ich bei einer TIBTable einen Standardwert für eine Spalte angeben, wo ich der Spalte ID den Generator angeben könnte?

Jens Schumann 27. Apr 2004 09:11

Re: Clientdaten und Generator
 
Zitat:

Zitat von Hansa
Das ist doch wohl alles vollkommen klar, so wie Du das machst. :mrgreen: Das geht wohl nicht anders. Wenn ich jetzt aber keine Unterknoten 8) usw. brauche, ws dann ? Z.B. schreibe ich eine Rechnung, die vorher eingegeben und dann abgespeichert wird. Geht das nun mit Generator/Trigger oder nicht (kein DBgrid, sondern Stringgrid). Wie gesagt : Lemmy... :shock:

Warum sollte das nicht gehen? Beim Post wird der Datensatz ohne ID abgeschickt. Bevor der Datensatz in der Tabelle gespeichert wird feuert der Trigger und holt den Wert für die Spalte ID über den Generator.

Jens Schumann 27. Apr 2004 09:15

Re: Clientdaten und Generator
 
Zitat:

Zitat von Quake
Erstmal ein allgemeine Frage, ein z.B. CREATE TABLE muss ich doch nicht commiten, oder?

Ich habe hier einfachdie Metadaten kopiert.



Zitat:

Zitat von Quake
das mit dem Trigger funzt aber nicht in sofern, das es noch ein bissl komplizierter wird es gibt noch eine Untertabelle von B, die Tabbelle C bei der ich die ID des Records aus B benötige. Und bei einem Trigger bekomme ich die ID der Tabelle B nicht zurück.
Ich glaube, ich muss die Tabelle B wohl extra per Code behandeln. Soll heißen für meine Tab. B verwende ich auch ein TIBDataSet.
Dabei kann ich die Eigenschaft GeneratorField setzen und ich filtere dann die Records der Tab. B bei dem AfterScroll Ereignise
der Tab. A. Dann steht mir auch die ID der Tab. B in der Tab. C zur verfügung.

Genau dafür habe die Sache mit der Storedprocedure geschrieben!!!
Dann muss beim Post (also beim Insert) für Tabelle B natürlich die ID mitgeliefert werden.
Diese ID hat man vorher über die Storedprocedure geholt, weil man die ID ja für Tabelle C braucht.
Der Trigger erkennt, ob der Datensatz einen Wert für ID enthält.

Quake 27. Apr 2004 09:35

Re: Clientdaten und Generator
 
Du meinst also, ich hole mir erst die Id vom Gernerator und schreibe sie in meine Tabelle im Formular und die damit verknüpfte TIBTable schreibt die ID samt der anderen Daten in die Datenbank? Dann kann ich ja beim BeforePost Ereignis der TIBTable die ID holen.

Dazu brauche ich doch keine StoredProcedure. Das kann ich ja auch mit einer Query machen.

Code:
select GEN_ID(MY_GENERATOR,1) as NewID from RDB$DATABASE;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:14 Uhr.
Seite 1 von 2  1 2      

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