Announcement

Collapse
No announcement yet.

IBX Master-Detail mit TIBDataSet

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

  • IBX Master-Detail mit TIBDataSet

    Hallo Zusammen!

    Nachdem ich ohne Ende Ärger mit der BDE hatte, habe ich mich nun durchgerungen, mein aktuelles Projekt vollständig auf den Firebase embedded umzustellen. Das Anlegen mit der IBOConsole hat auch alles super geklappt und ich muss gestehen, ich bin auch sehr begeistert davon.

    Zunächst hatte ich überlegt, sämtliche TTable-Komponenten einfach gegen TIBTable zu tauschen. Da aber ohnehin noch einiges an Umstellungsaufwand notwendig ist und ich nun ohnehin die ganze Anwendung nochmal auseinandernehmen muss, wollte es dann auch ordentlich machen und gleich mit TIBDataSet arbeiten.

    Leider gelingt mir jedoch die Master-Detail-Verknüpfung noch nicht richtig. Auch die Recherche in verschiedenen Foren und auch Google hat mich nicht wirklich zum Ziel führen können.

    Ich habe zunächst nur mal mit zwei Tabellen begonnen. In der Tabelle T_Objekt gibt es die Felder ID_OBJEKT, STRASSE, PLZ, ORT, INDABRTEXT und in der Tabelle T_Jahr gibt es die Felder ID_JAHR, ID_OBJEKT, JAHR. Ziel ist es, zu jedem Objekt eine beliebige Zahl von Jahren anzulegen.

    Die META-Daten:

    SET SQL DIALECT 3;

    /* CREATE DATABASE 'NK2007.fdb' PAGE_SIZE 4096

    DEFAULT CHARACTER SET NONE */
    /* Domain definitions */
    CREATE DOMAIN "BOOL" AS SMALLINT
    CHECK ((VALUE = 0) OR (VALUE = 1));
    CREATE DOMAIN "DECIMALANTEILE" AS DECIMAL(9, 4);
    CREATE DOMAIN "EURO" AS DECIMAL(9, 2);
    CREATE DOMAIN "FLOATQM" AS FLOAT
    CHECK (VALUE >= 0);
    CREATE DOMAIN "INTID" AS INTEGER;
    CREATE DOMAIN "INTJAHR" AS INTEGER
    CHECK ((VALUE >= 1900) AND (VALUE <= 2099));
    CREATE DOMAIN "INTSORT" AS INTEGER;
    CREATE DOMAIN "SMALLINT" AS SMALLINT;
    CREATE DOMAIN "STR10" AS VARCHAR(10);
    CREATE DOMAIN "STR100" AS VARCHAR(100);
    CREATE DOMAIN "STR20" AS VARCHAR(20);
    CREATE DOMAIN "STR250" AS VARCHAR(250);
    CREATE DOMAIN "STR30" AS VARCHAR(30);
    CREATE DOMAIN "STR50" AS VARCHAR(50);

    /* Table: T_JAHR, Owner: SYSDBA */

    CREATE TABLE "T_JAHR"
    (
    "ID_JAHR" INTID NOT NULL,
    "ID_OBJEKT" INTID NOT NULL,
    "JAHR" INTJAHR ,
    CONSTRAINT "PK_T_JAHRE" PRIMARY KEY ("ID_JAHR")
    );

    /* Table: T_OBJEKT, Owner: SYSDBA */

    CREATE TABLE "T_OBJEKT"
    (
    "ID_OBJEKT" INTID NOT NULL,
    "STRASSE" STR50 ,
    "PLZ" STR10 ,
    "ORT" STR50 ,
    "INDABRTEXT" STR250 ,
    "BEMERKUNG" STR250 ,
    CONSTRAINT "PK_T_OBJEKT" PRIMARY KEY ("ID_OBJEKT")
    );

    /* Index definitions for all user tables */

    CREATE INDEX "IDX_T_OBJEKT_STRASSE" ON "T_OBJEKT"("STRASSE");
    ALTER TABLE "T_JAHR" ADD CONSTRAINT "FK_T_JAHR_OBJEKT" FOREIGN KEY ("ID_OBJEKT") REFERENCES "T_OBJEKT" ("ID_OBJEKT") ON UPDATE CASCADE ON DELETE CASCADE;

    CREATE GENERATOR "GEN_JAHR_ID";
    CREATE GENERATOR "GEN_OBJEKT_ID";
    SET TERM ^ ;


    /* Triggers only will work for SQL triggers */

    CREATE TRIGGER "TRIG_JAHR_ID" FOR "T_JAHR"
    ACTIVE BEFORE INSERT POSITION 0
    as
    BEGIN
    NEW.ID_JAHR = GEN_ID (GEN_JAHR_ID, 1);
    END
    ^

    CREATE TRIGGER "TRIG_OBJEKT_ID" FOR "T_OBJEKT"
    ACTIVE BEFORE INSERT POSITION 0
    as
    BEGIN
    NEW.ID_OBJEKT = GEN_ID (GEN_OBJEKT_ID, 1);
    END
    ^

    COMMIT WORK ^
    SET TERM ;^

    /* Grant Roles for this database */


    /* Grant permissions for this database */

    In Delphi habe ich dann zwei IBDataSets und zwei Grids zum Testen benutzt. Im IBDataSet für T_Jahr habe ich folgende SQLs hinterlegt (bzw. mit dem Datenmengen-Editor angelegt).

    SelectSQL:
    select * from T_JAHR
    WHERE ID_OBJEKT = :ID_OBJEKT

    RefreshSQL:
    Select
    ID_JAHR,
    ID_OBJEKT,
    JAHR
    from T_JAHR
    where
    ID_JAHR = :ID_JAHR

    InsertSQL:
    insert into T_JAHR
    (ID_OBJEKT, JAHR)
    values
    (:ID_OBJEKT, :JAHR)

    ModifySQL:
    update T_JAHR
    set
    ID_OBJEKT = :ID_OBJEKT,
    JAHR = :JAHR
    where
    ID_JAHR = :OLD_ID_JAHR

    DeleteSQL:
    delete from T_JAHR
    where
    ID_JAHR = :OLD_ID_JAHR


    Das Ganze funktioniert auch eigentlich ganz prima, was den SELECT-Bereich angeht. Sobald ich im Objekt-Grid einen Datensatz auswähle, werden auch im Jahr-Grid nur die entsprechenden Datensätze angezeigt.

    Was jedoch noch nicht läuft, ist die Anlage eines Datensatzes. Hier wollte das Feld ID_OBJEKT eigentlich mit der ID_OBJEKT von T_OBJEKT automatisch belegt werden. Zumindest klappte das mit der BDE so immer.

    DataSource von der TIBDataSet der T_JAHR steht auch auf die DataSource, die mit TIBDataSet von T_OBJEKT verbunden ist.

    Vielleicht hat jemand eine Idee, wie man dieses Problem in den Griff bekommt.

    Vielen Dank schon mal im Voraus.

    Viele Grüße
    Christoph

  • #2
    Viele Möglichkeiten

    Hallo, es gibt ein paar Wege :

    in den Methoden von IBDataset nimmst Du : OnAppend und schreibst dann Hinein , was beim hinzufügen passieren soll. Zum Beispiel

    T_JahrID_Object.value := T_ObjectID_Object.value

    oder eine stored_Procedure in die Datenbank schreiben, welcher Du die Daten als Parameter weiter gibst. Hat Vorteile bei vielen Usern, da die EEinträge sofort geschrieben werden.

    Grüßle

    Comment

    Working...
    X