1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Foreign Key mittels der contains-abfrage?

Dieses Thema im Forum "PostgreSQL" wurde erstellt von Kampfgummibaerlie, 1 Januar 2018.

  1. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    Mein anliegen wäre jetzt, dass ich möchte, dass sich die lower(mietzeit) von meiner Tabelle Vermietungen in der in der Tabelle Öffnungszeiten enthaltenen Timerange/s liegt.

    Muss ich mir da einen Foreign Key einbauen? Oder doch eine Check Constraint, die ich bisher versucht habe, er aber am Ende meinte "missing from ..."

    Wäre wie immer sehr dankbar über das erreichen von mehr Wissen über das Ganze ;)

    Beispiel:
    Öffnungszeit(Montag) von 14:00 bis 18:00

    Ich möchte jetzt mittels einem Check Constraint oder Foreign Key irgendwie lösen, damit kein Startwert der vor 14:00 bzw. nach 18:00 eintragbar ist. Die Upper(tsrange) lassen wir ersteinmal, weil Mutter nichts dagegen hat, wenn sie ein wenig länger durt bleibt, solange der Kunde vor 18:00, oder wann sie auch immer an dem Tag zusperrt, dort ist.

    Wäre euch natürlich, wie immer, sehr dankbar ;D

    Da ich ja nicht allzuviel "Traffik" saugen möchte, würde ich das eben gerne über einen Constraint oder Foreign Key machen, und nicht zwangshaft über die Kombinierung von endlos vielen Funktionen.

    Anbei, fällt mir ein, jetzt am Ende, ist das über eine/mehrere Trigger Procedure/s möglich? (Ja, ich werde auch selbst ein wenig nachdenken darüber ;) )
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ranges können nicht als Foreign Keys verwended werden, auch mit einem Check Constraint wirst das nicht hinbekommen. Ein TRIGGER sollte aber gehen.
     
  3. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    Darf ich wieder um ein wenig Hilfe bitten?
    Spiele mich schon eine Weile dabei, eine "einfachere" Methode mal zu lösen.:

    Code:
    create or replace function valueint() returns trigger as $$
    begin
    if new.two.id > max(one.id) from one, two
    then raise exception 'Sorry';
    end if;
    return new;
    end;
    $$ language plpgsql;
    
    wo wäre die from-klausel richtig? bzw. wie würde diese trigger-procedure richtig?
    ich habe eine tabelle one, mit einer spalte id als integer
    ich habe eine tabelle two, mit einer spalte id als integer
    ich will checken, dass, wenn ich einen wert in table 2 eingebe, der wert größer ist, als der größte wert der tabelle one.

    Errormeldung sieht so aus:
    ERROR: invalid reference to FROM-clause entry for table "two" LINE 1: SELECT new.two.id > max(one.id) from one, two

    Danke, wie immer :)
     
  4. akretschmer

    akretschmer Datenbank-Guru

    vereinfacht, aber ich denke, damit kommst Du weiter:

    Code:
    test=*# create table oeffnungszeiten(tag int, von_bin int4range);
    CREATE TABLE
    test=# insert into oeffnungszeiten values (1, '(10,18]');
    INSERT 0 1
    test=*# create table ausleihe (tag int, von_bis int4range);
    CREATE TABLE
    test=*# create or replace function check_ausleihe() returns trigger as $$begin if (select count(1) from oeffnungszeiten where tag = new.tag and von_bis @> new.von_bis) then return new; else raise exception 'sorry'; end if; end;$$language plpgsql;
    CREATE FUNCTION
    test=*#
    test=*#
    test=*# create trigger check_trigger before insert on ausleihe for each row execute procedure check_ausleihe();
    CREATE TRIGGER
    test=*#
    test=*#
    test=*# insert into ausleihe values (1, '[12,16)');
    INSERT 0 1
    test=*# select * from ausleihe ;
     tag | von_bis
    -----+---------
      1 | [12,16)
    (1 row)
    
    test=*# insert into ausleihe values (1, '[8,20)');
    FEHLER:  sorry
    test=*#
    
     
    Kampfgummibaerlie gefällt das.
  5. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    Code:
    begin
    if (
      select lower(oeffnungszeit) from oeffnungszeiten, vermietungen
       where oeffnungszeiten.wochentag_id
         = wochentag_datum(lower(new.mietzeit)::date) and
      lower(mietzeit)::time > lower(oeffnungszeit)
    ) then return new; else raise exception 'sorry'; end if;
    end;
    
    Trigger muss ich deutlich üben ^^

    Folgendes Problem:
    er gibt den Error "Sorry" zurück, obwohl er eigentlich gerade offen haben sollte?

    Gehe ich jetzt zu schnell ins Thema? Ifs wäre das Thema, mit dem ich mich befassen müsste. Trigger sind mir ja schonmal gelungen.
     
  6. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    War vorher bei Eltern im Haus, und konnte es nur überfliegen. Bin wieder zuhause, werde später dann noch Abendessen, aber um deine Syntax/e(?) zu korrigieren:

    Gleich im 1. create table-Syntax ist ein Fehler, auf den ich nur für alle anderen hinweise:
    Es sollte statt dem von_bin ein von_bis drinnen stehen ;)

    Und ja, herr Elefant, Fehler sind Menschlich ;)

    EDIT 2:
    Beim bissl herumbasteln und in der Praxis anwenden funktioniert das Prinzip exakt so, wie ich es gerne hätte, nur habe ich dabei einen Gedanken, der womöglich nicht damit funktionieren würde, weil Mutter ja doch öfters, für eher ... reife Personen, die nicht allzuschnell sind, ein paar Minuten länger offen hat. entsprechend würde ich versuchen, nur den Anfangszeitpunkt zu kontrollieren, dass er innerhalb der Öffnungszeit liegt, der "Bis-Wert" kann ja x-beliebig sein.

    Aber ja, ich hoffe, dass das alles noch was wird :D
     
    Zuletzt bearbeitet: 2 Januar 2018
  7. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    Code:
    create function nut() returns trigger as $$
    begin
    if (table2.int @> table1.pos_int) then return new; else raise exception 'sorry'; end if;
    end;$$
    language plpgsql;
    
    ist die Function, habe auch einen Trigger gebaut für table2, die for each row die oben gegebene function executed, jedoch bekomme ich folgenden error:

    ERROR: error CONTEXT: PL/pgSQL function nut() line 3 at RAISE SQL-Status: P0001

    Warum ich nicht einfach mr. Elephants Lösung nehme?
    Weil ich das Thema verstehen möchte ^^
     
  8. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    werde mich mit funktionen beschäftigen, die einen boolean value returnen.
    weil man dort offenbar IMMER eine if-klausel einbauen muss, damit sie boolean returnen können.

    hier eine nette (kleine) Funktion :D
    Code:
    create function positiv(x integer) returns boolean as 'begin if x > 0 then return true; else return false; end if; end;' language plpgsql;
    
    EDIT: Zur Erklärung: sie sagt "true", falls der Parameter über 0 ist, anderenfalls eben "false".
     
  9. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    *im Kreis renn*

    Ich habe es endlich geschafft xD
    Ich glaube es lag am falschen Textverständniss von mir.

    Ich habe einen Trigger erstellt, der sich nicht before auslöst, sondern eben einen, der sich erst nach dem insert "zündet".
    Anbei habe ich das Ganze auch ein wenig anders verwendet, und die Int4Range auf tsrange, und was weiß ich was alles gemacht :)

    Danke, kann ich schlafen gehen ! :D
     
  10. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    heute morgen funktionierts irgendwie nicht, ...

    Folgender Code steht (jetzt) in meiner Trigger Procedure:
    Code:
     begin if (select wochentag_datum(lower(orders.ordertime)::date) = openings.weekday and openings.opening @> lower(ordertime)::time from orders, openings) 
    then return new; else raise exception 'Nicht möglich'; end if; end; 
    
    Er gibt mir jedoch immer den Error aus, selbst wenn in openings ein weekday steht, welcher wiederum dem wochentag vom datum der "Startzeit" ist.
     
  11. Kampfgummibaerlie

    Kampfgummibaerlie Datenbank-Guru

    Habe mir eine halbwegs funktionierende "gebaut":

    Code:
     begin if (select count(1) from oeffnungszeiten
    where wochentag_id = wochentag_datum(lower(new.mietzeit)::date) and oeffnungszeiten.oeffnungszeit::timerange @> lower(new.mietzeit)::time) then return new; else raise exception 'sorry'; end if; end;
    
    Scheint auch zu funktionieren (der obige Code ist in der Trigger-Procedure/Trigger-Function)
     
Die Seite wird geladen...

Diese Seite empfehlen