Ausnahme-Constraints mit Ausnahme/n?

Kampfgummibaerlie

Datenbank-Guru
Beiträge
728
Mein momentanes Problem wäre, dass ich jeweils einen solchen Constraint gesetzt habe, dass nicht 1 Kunde mehrere Maschinen mieten kann, aber auch keine Maschine mehrmalig mietbar ist.

Jetzt komme ich auf das folgende Problem:
Ich möchte nicht jeden Kunden vorher anmelden, habe entsprechend in der "Standarddatenbank" bereits einen Kunden mit Namen "Anonym" inkludiert, welcher aber, wegen dem Kunden-Constraint nur einmal verwendbar ist.....

kann man die constraints vl. irgendwie ala dem hier setzen? (Bin ja unwissend xD):

Code:
exclude using gist(Kunden_Name with!='Anonym', Mietzeit with &&));

Weil, wenn das geht, würde ich auch gerne einen Count einbauen, welcher zählt, wieviele "Maschinen_Name" mit "Normal" gefüllt sind, und dass dort höchstens 4 Maschinen des Namen "Normal" sein dürfen.

Damit man den Namen nicht komplett eingeben muss, weil ja doch recht "wenig" Maschinen vorhanden sind, würde ich das Ganze (würde ich gerne selber dazuschreiben) würde ich das ganze mit 'x'% regeln, oder wie es auch immer aussehen würde ;) (Ja, ich will selbst draufkommen, wie das aussehen muss, ich brauche nur hier und da einen Tipp/Rat ;) )
 
Werbung:
Code:
exclude using gist(wunden_name with =, mietzeit with &&) where (kunden_name != 'Anonym'))

Nicht getestet jetzt. Das mit 'höchstens 4' wird schwer. Mit den Maschinennamen: verwende dazu eine Stammdaten-Tabelle für die Maschinen und in der Verleih-Tabelle nur einen Foreign Key..

Kurztest:

Code:
test=*# create table verleih(geraet int, dauer daterange, exclude using gist(geraet with =, dauer with &&) where (geraet > 0));
CREATE TABLE

geraet also als INT, Geraet = 0 wäre ein beliebiges Gerät (sorry, tausche Geraet gegen Kunde) der Foreign Key ist hier nicht dargestellt.
 
Erstellen der Tabelle:

Code:
create table vermietungen2 (Vermietungs_ID bigserial unique primary key, Kunden_name text, Maschinen_ID int, Mietzeit tsrange default tsrange(now()::timestamp without time zone, 'infinity'::timestamp without time zone), exclude using gist(Maschinen_ID with =, Mietzeit with &&), exclude using gist(Kunden_name with =, mietzeit with &&) where (kunden_name != 'Anonym'));

Werde noch den nötigen Feinschliff und die Foreign-Keys setzen, aber ja, es funktioniert !

Folgende Reihenfolge geht:
1.:
Code:
INSERT INTO public.vermietungen2(
   kunden_name, maschinen_id)
   VALUES ('Anonym', '1');

2.:
Code:
INSERT INTO public.vermietungen2(
   kunden_name, maschinen_id)
   VALUES ('Anonym', 2');

3.:
Code:
INSERT INTO public.vermietungen2(
   kunden_name, maschinen_id)
   VALUES ('Werner', '3');

4.:
Code:
INSERT INTO public.vermietungen2(
   kunden_name, maschinen_id)
   VALUES ('Anonym', '3');


(gewollter) Error:
FEHLER: kollidierender Schlüsselwert verletzt Exclusion-Constraint »vermietungen2_kunden_name_mietzeit_excl« DETAIL: Schlüssel (kunden_name, mietzeit)=(Werner, ["2017-05-26 12:08:21.81981",infinity)) kollidiert mit vorhandenem Schlüssel (kunden_name, mietzeit)=(Werner, ["2017-05-26 12:08:17.824418",infinity)).

5.:
Code:
INSERT INTO public.vermietungen2(
   kunden_name, maschinen_id)
   VALUES ('Werner', '1');

(gewollter) Error:
FEHLER: kollidierender Schlüsselwert verletzt Exclusion-Constraint »vermietungen2_maschinen_id_mietzeit_excl« DETAIL: Schlüssel (maschinen_id, mietzeit)=(5, ["2017-05-26 12:13:30.328534",infinity)) kollidiert mit vorhandenem Schlüssel (maschinen_id, mietzeit)=(5, ["2017-05-26 12:11:39.702978",infinity)).

Die Zusammenhänge werde ich alleine schaffen :D
Aber, ich glaube, ich habe nur nicht daran gedacht, noch einmal Klammer auf und Klammer zu zu setzen.

Mein lieber mr. Elephant, ist es ernsthaft so hart schwer, eine schöne Oberfläche zu bauen?
Schwester meint, sie hat das Jahre lange lernen müssen, die im anderem Forum meinen, ich sollte mir Guides erstmal durchlesen, und so weiter...
 
Nicht getestet jetzt. Das mit 'höchstens 4' wird schwer. Mit den Maschinennamen: verwende dazu eine Stammdaten-Tabelle für die Maschinen und in der Verleih-Tabelle nur einen Foreign Key..

Kann man kein Limit setzen in einer Constraint, die alle Reihen zählt, welche zur selben Zeit "aktiv" sind, sprich kein "Upper(Mietzeit)" haben, und das gleiche Datum?
 
Ich versuche gerade irgendwie die vorigen Codes in die Datenbank zu bringen ;)

Arbeite mit einer identischen 2. Datenbank, wo alle Tabellen annähernd gleich heißen, und ja, erst wenns dort passt, bring ichs in die andere.
 
Werbung:
Junger, es wird kompliziert xD

Weil, ich würde gerne irgendwie hinbekommen, dass man >nicht< den ganzen Maschinennamen angibt, sondern zum Beispiel nur:
select Mietbeginn('Ernst', 'Norm'), und er trägt Ernst zu einer normalen Maschine ein, welche halt gerade frei ist.

Ich glaube aber, dafür müsste ich mich damit auseinandersetzen, dass ich mehrere IFs in eine Function schreibe, wo ich bisher irgendwie nicht dahinter kam :/

Gibt es ein "++" in Postgres? Ich glaube, das gabs in C++, und hat irgendwas mit +1 bewirkt.
Stelle ich mir gerade vor, dass er im elseif die nächste Reihe prüft, auf Maschinen mit dem Namen "Norm....", und schaut, ob dese Verfügbar ist, und so weiter xD

PROJEKT DATENBANK:
Es hat mal klein angefangen, und wird immer komplizierter, glaube ich hast du (Akretschmer) eh schonmal gesagt ;)

hahahaha, nächster Einfall (geht aber bestimmt, habe ich im OpenOffice Programm verwendet) wäre, alle Buchstaben klein machen, und alle Werte immer in Kleinbuchstaben vergleichen ;)

Edit: Habe das erste Wort ausgebessert, hoffe ich ist nicht anzufechten :/
 
Zurück
Oben