![]() |
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. |
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:
Der Trigger "TRG_KONSOTREE_0" feuert, bevor der Datensatz eingefügt wird. Interessant ist hier folgende Zeile
/* 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 ;^
Code:
Nur wenn die ID nicht mit gegeben wurde, wird der Inhalt für die ID aus dem Generator mit
if (new.id is null) then new.id=gen_id(gen_konsotree,1);
Code:
geholt.
gen_id(gen_konsotree,1)
Wenn ich den ID Wert benötige, bevor ich den Datensatz hinzufüge hole ich mir den nächsten Generatorwert über eine Storedprocedure:
Code:
Fazit: Als Lösung schlage ich Dir die Verwendung von Triggern vor.
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; Folgendes Buch kann ich schwer empfehlen: ![]() |
Re: Clientdaten und Generator
Hierzu habe ich eine Frage :
Zitat:
|
Re: Clientdaten und Generator
Zitat:
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. |
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:
|
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 |
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?
|
Re: Clientdaten und Generator
Zitat:
|
Re: Clientdaten und Generator
Zitat:
Zitat:
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. |
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 06:23 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 by Thomas Breitkreuz