Home Forum Nuclos Konfiguration Vorgänge und Objekte ID-Factory für virtuelles BO

Ansicht von 10 Beiträgen - 1 bis 10 (von insgesamt 10)
  • Autor
    Beiträge
  • #9522
    Hans Dengel
    Teilnehmer

    Hallo Forum, hallo Support,

    ich möchte ein virtuelles BO nutzen, um darüber auch Daten in die Datenbank zu schreiben. Das Wiki gibt dazu leider recht wenig her, (ID Factory Beispiel steht noch auf ToDo…). Ich habe jetzt einfach mal eine Funktion als Datenbankobjekt angelegt, die einfach SELECT nextval(’nuclos.idfactory‘) aufruft und die ID zurückgibt, hab mal getippt daß das ein bigint ist….

    CREATE OR REPLACE FUNCTION DEF_VBONEXTID()
    RETURNS bigint AS
    $BODY$
    BEGIN
    SELECT nextval(nuclos.idfactory);
    END
    $BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100;
    ALTER FUNCTION DEF_VBONEXTID()
    OWNER TO nuclos;

    Das SELECT Statement liefer auch brav die nächste ID der Sequenz, wenn man das im pgadmin aufruft.

    Im BO Wizard, lässt sich diese Funktion dann auch als ID-Factory auswählen, das BO wir „änderbar“ und im Layout des VBOs kann ich auch was ändern. Nur beim Speichern gibt es einen Fehler.
    Da entgeht mir offenbar noch was im Verständnis. Können die Profis da Tips, oder noch besser, ein Beispiel geben ?

    Grüsse Hans

    #9524
    Fry123
    Teilnehmer

    Hallo,
    Ja da entgeht dir was. Ein Virtuelles BO ist nur eine Datenbank View ohne richtige Tabelle dahinter. Das bedeutet ein direktes Speichern in diese ist nicht möglich.
    Ich vermute das die die Fehlermeldung irgendwas mit Triggern sagen wird.
    Lösung was bei uns das wir der View erst noch sagen müssen wohin es seine Daten speichern muss. Ich habe mal ein Beispiel Abgehangen für eine Update Regel. Da wir nur API-Regeln auf dem BO ausführen wollen nutzen wir hier das „DO INSTEAD NOTHING“. dort kann man aber auch die Daten weiterleiten an eine echte Tabelle.

    Quelltext:

    CREATE or REPLACE RULE [RULE_NAME] AS
    ON UPDATE TO [VIEW_NAME{also die des Vbo}]
    DO INSTEAD NOTHING

    Löschanweisung:

    DROP RULE IF EXISTS [RULE_NAME] ON [VIEW_NAME{also die des Vbo}]

    https://www.postgresql.org/docs/9.5/static/sql-createrule.html

    MFG

    #9525
    Hans Dengel
    Teilnehmer

    Hallo Fry123,
    erstmal Danke.
    Das mit der view ist mir schon bekannt. Die view für das virtuelle BO ist aber eine updatable view, keine joins, Group by, Aggregation usw. Daher bin ich davon ausgegangen mit der idfactory für das virtuelle BO legt man die Sequence für die intid fest. Wenn das aber so ist wie du sagst, ist der Name idfactory vielleicht etwas irreführend. Aber die update bzw. auch Insert Rule probier ich mal aus. Auch wenn die note in dem von dir angehängten link sagt, dass die rule für hinreichend einfache views nicht nötig ist. Daher wäre ein Beispiel im Wiki ja auch schön… 😉

    Mfg

    Hans

    #9526
    Fry123
    Teilnehmer

    Wie ist den die Fehlermeldung?

    #9527
    Thomas Hempel
    Teilnehmer

    Ich kann zwar nichts beitragen, außer dass mir der Support mal gesagt hat: „Ja das geht, wir haben da eine Lösung“..

    Will sagen, an der Lösung wäre ich auch seeehr interessiert!

    #9528
    Frank Pavlic
    Teilnehmer

    Hallo,
    ich habe änderbare virtuelle BOs im Einsatz. Kannst Du mal einen Stacktrace des Fehlers posten ? Auch wäre deine Virtuelle-BO-SQL sicher hilfreich bei der Fehlersuche.

    Gruß
    Frank

    #9529
    Hans Dengel
    Teilnehmer

    Hallo Frank,

    ich habe das jetzt mal als BOTest und VBOTest ohne viel drumherum probiert.

    Die Definition des VBOTest:

    CREATE OR REPLACE VIEW DEF_VBOTEST AS
    SELECT
    def_botest.intid INTID,
    def_botest.stritem1,
    def_botest.stritem2,
    def_botest.datcreated DATCREATED,
    def_botest.strcreated STRCREATED,
    def_botest.datchanged DATCHANGED,
    def_botest.strchanged STRCHANGED,
    def_botest.intversion INTVERSION
    FROM
    def_botest;

    CREATE OR REPLACE RULE VBOTEST_UPDATE AS ON UPDATE TO DEF_VBOTEST
    DO INSTEAD
    UPDATE def_botest
    SET stritem1 = NEW.stritem1,
    stritem2 = NEW.stritem2
    WHERE intid = OLD.INTID;

    CREATE OR REPLACE RULE VBOTEST_INSERT AS ON INSERT TO DEF_VBOTEST
    DO INSTEAD
    INSERT INTO def_botest VALUES (DEF_VBONEXTID(), NEW.stritem1, NEW.stritem2,now());

    Das Update funktioniert dann schonmal. Aber beim INSERT geht nix. Oben ist der letzte Versuch bisher, es wird dann gemeldet die Funktion def_vbonextid() existiert nicht. In der DB ist die aber sehr wohl und sieht so aus…..

    CREATE OR REPLACE FUNCTION DEF_VBONEXTID()
    RETURNS bigint AS
    $BODY$
    BEGIN
    SELECT nextval(‚IDFACTORY‘);
    END
    $BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100;
    ALTER FUNCTION DEF_VBONEXTID()
    OWNER TO nuclos;

    Was mache ich falsch ?

    Grüsse

    Hans

    #9530
    Frank Pavlic
    Teilnehmer

    Hallo Hans,
    hängst du noch deine Server-Logs mit den Fehlermeldungen des INSERTs an ? Dann kann ich es mir anschauen. Eines Vorweg, ich habe keine DB-RULE für Updates im Einsatz.

    Gruß
    Frank

    #9531
    Hans Dengel
    Teilnehmer

    Hallo Frank,

    die Insert Rule habe ich wieder gelöscht, und nur die Function für die IFFactory gelassen, und noch ein anderes Namenschema probiert. Anbei die Funktion und das Log wenn ich in stritem1 und stritem2 „Test“ neu eigeben will……

    Funktion DEF_VBONEXTID

    CREATE OR REPLACE FUNCTION DEF_VBONEXTID()
    RETURNS bigint AS
    $BODY$
    BEGIN
    SELECT nextval(„nuclosdevel.idfactory“);
    END
    $BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100;
    ALTER FUNCTION DEF_VBONEXTID()
    OWNER TO nuclos;

    Das Server Log ist im Anhang

    Kannst du evtl mal ein Beispiel, das funktionieren müssste posten ?

    Grüsse

    Hans

    Attachments:
    #9535
    Frank Pavlic
    Teilnehmer

    Hallo Hans,
    hat etwas gedauert, bis ich wieder ins Forum schauen konnte. Deine Log-Datei sagt „FEHLER: Spalte »nuclosdevel.idfactory« existiert nicht“ .
    Also folgendes habe ich getan.
    Folgende Funktion habe ich als Datenbankobjekt angelegt:

    CREATE OR REPLACE FUNCTION O37U_IDFACTORY()
    RETURNS Integer AS
    $BODY$
    DECLARE
    rc numeric(9,0);
    BEGIN
    SELECT NEXTVAL(‚IDFACTORY‘) into rc;
    RETURN rc;
    END;
    $BODY$
    LANGUAGE ‚plpgsql‘ VOLATILE
    COST 100;

    Wobei das Kürzel meines nuclets ist. Dann habe ich die VIEW als Datenbankobjekt angelegt, also per „CREATE OR REPLACE VIEW O37U_VIEW_BAUVORHABEN“ , wobei auch hier wieder O37U wieder die Zuordnung zu meinem nuclet darstellt.
    Anschliessend legst du eine neue BO an und weist dort die VIEW und die IDFACTORY-Funktion zu. Diese müssten auswählbar sein.
    Dann gehst du zu deiner Attributliste im Wizard und verbesserst noch ein wenig die Anzeigenamen und Datentypen, sprich du gehst ganz normal durch deinen BO-Wizard durch.
    Der Unterschied zu deiner IDFACTORY-Funktion ist ,dass ich explizit ein RETURN angebe. Was ich auch schon manchmal hatte, ist, dass die neuen Objekte erst einem nuclet zugeordnet werden sollten. Allerdings ist das schon ein paar nuclos-Versionen her, dass ich dieses Phänomen hatte. Und da ich mich immer daran halte, kann ich nicht sagen, ob es auch mit neueren nuclos-Versionen immer noch ist.

    Viel Erfolg.

    Gruß
    Frank

Ansicht von 10 Beiträgen - 1 bis 10 (von insgesamt 10)