Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: erweiterterte Fremdschlüssel Beziehung?!

  1. #1
    mweasty ist offline Neuer Benutzer
    Registriert seit
    08.12.2009
    Beiträge
    6

    Standard erweiterterte Fremdschlüssel Beziehung?!

    Ich habe folgendes Problem, vielleicht könnt ihr mir helfen:

    Ich habe eine Tabelle in der sogenannte Ontologie-Begriffe gespeichert sind, die aus verschiedenen Namensräumen kommen können (GO/ECO und andere).


    Ontology:
    -----------
    Code:
    ID             Kurzname        Namensraum             Beschreibung
    ECO:0000001    ECO             evidence_code          inferred by curator
    ECO:0000004    ECO             evidence_code          inferred from cell fractionation
    GO:0000006     GO              molecular_function     high affinity zinc uptake transmembrane transporter activity
    GO:0000007     GO              molecular_function     low-affinity zinc ion transmembrane transporter activity
    GO:0005737     GO              cellular_component     cytoplasm
    GO:0005783     GO              cellular_component     endoplasmic reticulum
    Sie haben alle dieselbe Form weshalb es meines Erachtens nach sinnvoll ist, sie alle in eine Tabelle zu schreiben. Allerdings erschwert mir das, die klare Definition von Fremdschlüsselbeziehungen.

    Stellen wir uns eine weitere Tabelle vor, die auf einen ganz bestimmten Namensraum von diesen Ontologie-IDs mit Fremdschlüssel verweisen soll. Zum Beispiel eine Tabelle die Kompenenten mit Lokalisierungsinformationen verknüpft. (für die biologisch-bewanderten unter Euch: in welchem compartment, tissue, taxon befindet sich ein bestimmtes Protein)

    Tabelle Lokalisation
    ---------------------
    Code:
    Protein                 Compartment 
    Alkoholdehydrogenase    GO:0005737
    Was ich jetzt natürlich möchte ist das diese Spalte Compartment einerseits auf die Spalte ID aus meiner oberen Tabelle verweist, aber natürlich nicht auf die Namensräume "evidence_code" und "molecular_function".

    Kann ich in irgendeinerweise einen Check Constraint setzen ? Oder wie müsste die Fremdschlüsseldefintion aussehen damit ich nur die "spezielle Teilmenge" aus Tabelle "Ontology" als zulässige IDs für Tabelle "Lokalisation" zulasse.

    Ich hoffe ich konnte einigermaßen rüberbringen, was ich meine.

    Vielen Dank schonmal für Eure Antworten
    Micha

    PS: Ich benutze PostgreSQL 8.4.1

  2. #2
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von mweasty Beitrag anzeigen

    Kann ich in irgendeinerweise einen Check Constraint setzen ? Oder wie müsste die Fremdschlüsseldefintion aussehen damit ich nur die "spezielle Teilmenge" aus Tabelle "Ontology" als zulässige IDs für Tabelle "Lokalisation" zulasse.

    Ich hoffe ich konnte einigermaßen rüberbringen, was ich meine.

    Vielen Dank schonmal für Eure Antworten
    Micha

    PS: Ich benutze PostgreSQL 8.4.1
    Ich denke mal, Du wirst um einen TRIGGER nicht herumkommen.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #3
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Ich denke mal, Du wirst um einen TRIGGER nicht herumkommen.

    Andreas
    Code:
    test=# select * from onko ;
         id     |     namensraum
    ------------+--------------------
     GO:0000006 | molecular_function
     GO:0005737 | cellular_component
    (2 rows)
    
    test=*# select * from lokalisation ;
     protein | compartment
    ---------+-------------
    (0 rows)
    
    test=*# create or replace function check_onko() returns trigger as $$begin perform * from onko where id=new.compartment and namensraum='cellular_component'; if found then return new; else raiseexception 'das geht so ned'; end if; end;$$ language plpgsql;
    CREATE FUNCTION
    test=*# create trigger trg1 before insert on lokalisation for each row execute procedure check_onko();
    CREATE TRIGGER
    test=*# insert into lokalisation values ('Alkoholdehydrogenase','GO:0005737');
    INSERT 0 1
    test=*# insert into lokalisation values ('irgend was','GO:0000006');
    ERROR:  das geht so ned
    test=!#
    mal so als Spielerei ...


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  4. #4
    mweasty ist offline Neuer Benutzer
    Registriert seit
    08.12.2009
    Beiträge
    6

    Standard

    Ich habe auf den meisten Tabellen schon einen After-Trigger weil ich so eine Art Protokoll-Tabellen habe, wo ich nach jeder Einfügeoperation die ursprünglichen Werte nochmal sichere.

    Meines Wissens wäre diese Art von Test ja ein Before Trigger, da ich ja nicht möchte das etwas eingefügt wird, wenn die Bedingung verletzt ist.

    Meines Wissens nach ist es möglich sowohl einen Before als auch einen After Trigger pro Tabelle zu definieren. Könntest du mir ansatzweise zeigen, wie so ein Before Trigger aussehen müsste. Oder mich auf eine geeignete Seite verweisen wo ich fündig werde ?

    Code:
    CREATE TRIGGER tr_check_namespace Before INSERT OR UPDATE OR DELETE
        ON "localisation" FOR EACH ROW
        EXECUTE PROCEDURE sp_check_namespace();
    was genau müsste in den Body meiner Funktion (SP)? oder kann ich das ganze schon direkt im Trigger abhandeln ?

    So ähnlich sieht mein After Trigger aus
    Code:
    CREATE OR REPLACE FUNCTION sp_check_namespace()     
    RETURNS trigger AS
    $BODY$
        BEGIN
                ....
        END;
    $BODY$
        LANGUAGE PLpgSQL
        CALLED ON NULL INPUT
        VOLATILE
        EXTERNAL SECURITY INVOKER;

  5. #5
    mweasty ist offline Neuer Benutzer
    Registriert seit
    08.12.2009
    Beiträge
    6

    Standard

    ui du warst schneller, mom ich schau mir kurz dein Beispiel an

    EDIT:
    -----------
    AH super, habs noch nit getestet, aber dein Beispiel ist super, glaube damit kriege ich das hin! Danke für die schnelle Antwort. Ich meld mich nochmal wenn es funzt

  6. #6
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von mweasty Beitrag anzeigen

    Meines Wissens nach ist es möglich sowohl einen Before als auch einen After Trigger pro Tabelle zu definieren.
    Nicht ganz korrekt, du kannst beliebig viele definieren. Sie feuern in alphabetischer Reihenfolge.

    Könntest du mir ansatzweise zeigen, wie so ein Before Trigger aussehen müsste. Oder mich auf eine geeignete Seite verweisen wo ich fündig werde ?
    Guggst Du anderes Posting von mir.

    Code:
    CREATE TRIGGER tr_check_namespace Before INSERT OR UPDATE OR DELETE
        ON "localisation" FOR EACH ROW
        EXECUTE PROCEDURE sp_check_namespace();
    was genau müsste in den Body meiner Funktion (SP)? oder kann ich das ganze schon direkt im Trigger abhandeln ?
    Beim Delete brauchst das wohl nicht zu prüfen ...


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  7. #7
    mweasty ist offline Neuer Benutzer
    Registriert seit
    08.12.2009
    Beiträge
    6

    Standard

    create or replace function import.check_compartment() returns trigger as $$begin perform * from term where identifier=new.identifier and namespace='cellular_component'; if found then return new; else raiseexception 'You have to provide a correct cellular component identifier i.e. ECO:0000004'; end if; end;$$ language plpgsql;
    was genau bedeutet "perform *" ?

  8. #8
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von mweasty Beitrag anzeigen
    was genau bedeutet "perform *" ?
    Sowas wie select, nur daß das Resultat verworfen wird, weil nicht wirklich benötigt.

    Btw., die Online-Doku hat eine brauchbare Suchfunktion, rechts oben ;-)

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  9. #9
    mweasty ist offline Neuer Benutzer
    Registriert seit
    08.12.2009
    Beiträge
    6

    Standard

    Ich hatte nach "perform postgres" gegoogelt, aber scheinbar den ersten Treffer gleich übersehen.

    Aus irgendeinem Grund bekomme ich folgenden Fehler, wenn ich deine Funktion leicht abgeändert versuche zu implementieren:

    Code:
    testdb=# create or replace function check_compartment() returns trigger as $$begin perform * from term where identifier=new.identifier and namespace='cellular_component'; if found then return new; else raiseexception 'You have to provide a correct cellular component identifier'; end if; end;$$ language plpgsql;        ERROR:  syntax error at or near "raiseexception"
    LINE 1: raiseexception 'You have to provide a correct cellular compo...
            ^
    QUERY:  raiseexception 'You have to provide a correct cellular component identifier'
    CONTEXT:  SQL statement in PL/PgSQL function "check_compartment" near line 1
    testdb=#
    Okay hat sich erledigt, hab nach raiseexception gegoogelt und herausgefunden, dass es auseinander geschrieben werden muss Sorry für meine voreilige Rückmeldung O.o Jetzt hats geklappt.
    Geändert von mweasty (08.12.2009 um 16:12 Uhr)

  10. #10
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von mweasty Beitrag anzeigen
    Ich hatte nach "perform postgres" gegoogelt, aber scheinbar den ersten Treffer gleich übersehen.

    Aus irgendeinem Grund bekomme ich folgenden Fehler, wenn ich deine Funktion leicht abgeändert versuche zu implementieren:

    Code:
    testdb=# create or replace function check_compartment() returns trigger as $$begin perform * from term where identifier=new.identifier and namespace='cellular_component'; if found then return new; else raiseexception 'You have to provide a correct cellular component identifier'; end if; end;$$ language plpgsql;        ERROR:  syntax error at or near "raiseexception"
    LINE 1: raiseexception 'You have to provide a correct cellular compo...
            ^
    QUERY:  raiseexception 'You have to provide a correct cellular component identifier'
    CONTEXT:  SQL statement in PL/PgSQL function "check_compartment" near line 1
    testdb=#
    raise exception, ist ein Copy&Paste - Fehler.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Antworten: 6
    Letzter Beitrag: 23.07.2010, 15:20
  2. Zwischentabelle erstellen? m zu n Beziehung
    Von zaibatsi im Forum PGAdmin
    Antworten: 3
    Letzter Beitrag: 13.06.2010, 13:59
  3. Frage 1:n Beziehung umgekehrt suchen
    Von maxx im Forum SQL
    Antworten: 8
    Letzter Beitrag: 09.06.2010, 06:47
  4. FK-Beziehung durch Trigger ersetzen
    Von benwen im Forum Trigger und Funktionen
    Antworten: 13
    Letzter Beitrag: 27.05.2007, 20:28
  5. Abfrage als Fremdschlüssel
    Von eremit im Forum Allgemeines
    Antworten: 4
    Letzter Beitrag: 20.02.2007, 10:38

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum