nicht verwendete ID zu Zeitpunkt finden

Kampfgummibaerlie

Datenbank-Guru
Beiträge
731
Soda, ich sitze seit Gestern an dem Thema, kam aber nicht wirklich drauf, wie es gehen könnte, ich habe das Ganze mit except versucht, glaube auch, dass es mittels einem solchen funktionieren sollte, nur glaube ich, baue ich die Function (!) falsch auf.

Ich habe, wie schon oft gehabt, Maschinen im Einsatz, oder auch nicht.
Das momentane Problem wäre, dass ich nur schwer arbeiten kann mit einem Unique-Constraint, weil ich sonst eben jeden Tag die gesamte Tabelle löschen müsste, bzw. eine Maschine nicht mehrfach an einem Tag vermietbar ist.
Ich habe es auch mit except probiert, was aber irgendwie (glaube ich) so ca. das gleiche tut, wie ein unique-constraint. (Bei meiner Anwendung)

ich habe da irgendwas gemacht, was ähnlich aussah:
Code:
select maschinen_id from maschinen except select maschinen_id from vermietungen

Mir ist klar, mag jetzt dumm aussehen, aber ich komme nicht dahinter, wie ich eine zukünftige Mietzeit mit einer freien Maschine fülle. (Ist das überhaupt möglich?)

Wäre sehr dankbar, für jeglichen Tipp, oder sonst etwas ;)

Anmerkung:
Ja, ich möchte eine Function bauen, weil diese in andere Functions eingesetzt werden kann, wenn der Typ übereinstimmt.
 
Werbung:
Ich habe es auch mit except probiert, was aber irgendwie (glaube ich) so ca. das gleiche tut, wie ein unique-constraint. (Bei meiner Anwendung)

Except schreibt man nicht nur anders als unique-constraint, es ist auch was anderes.

ich habe da irgendwas gemacht, was ähnlich aussah:

Interessant, aber für andere nicht hilfreich, zu verstehen, was Du genau gemacht hast.
 
Also ausführlicher:

1.: Ich habe eine Tabelle mit Maschinen erstellt (M_ID, M_Name)
2.: Ich habe eine Tabelle mit Vermietungen erstellt (V_ID, M_ID, TSRange)
3.: Ich habe eine insert-function erstellt ((M_ID, Timestamp) into vermietungen)

Was würde ich jetzt gerne tun:
Ich würde gerne eine Maschinen_ID mittels einer Function selecten, die zu einem gegebenen Timestamp "frei" wäre.
Sprich, ich möchte statt dem M_ID in oben genanntem Punkt 3 einfach nur eine function reinschreiben, welche eben eine "freie" ID wählt.

EDIT: ersetzt Timestamp mit TSRange, ich glaube, ich hätte länger schlafen sollen ^^
 
Zuletzt bearbeitet:
Code:
test=# create table maschinen(id int primary key, name text);
CREATE TABLE
test=*# insert into maschinen select s, 'maschine ' || s::text from generate_series(1,4) s;
INSERT 0 4
test=*# select * from maschinen ;
 id |  name   
----+------------
  1 | maschine 1
  2 | maschine 2
  3 | maschine 3
  4 | maschine 4
(4 Zeilen)

test=*# create table verleih (maschine int references maschinen, dauer daterange);
CREATE TABLE
test=*# insert into verleih values (1, '[2017-07-01,2017-07-30)');
INSERT 0 1
test=*# insert into verleih values (2, '[2017-07-01,2017-07-10)');
INSERT 0 1
test=*# insert into verleih values (3, '[2017-07-10,2017-07-20)');
INSERT 0 1

Preisfrage: welche maschine ist heute frei?

Code:
test=*# select id from maschinen except select maschine from verleih where dauer @> current_date;
 id
----
  2
  4
(2 Zeilen)
 
habe mir auch schon gedacht, dass ich einfach nur eine where einbauen muss, aber ich wüsste auf die Schnelle nicht, was genau das @ beschreibt, bzw. kann ich es nicht anwenden.

Ich fühle mich langsam schon mehr als Belastung für euch/dich ;)

EDIT: Ich mach mal Pause
 
Gut, lesen und mitdenken ist glaube ich mein größtes Problem ^^

er meinte, wie ich 1:1 deinen Code nur ein wenig umgeschrieben habe, und angewandt, dass der Operator nicht existiert, kaum das current_date zu einem timestamp gemacht (current_date::timestamp), hat es funktioniert ;)

Ich glaube, ich reite quasi "ununterbrochen" auf maximaler Lernfähigkeit herum, wenn ich mich damit beschäftige, und übersehe doch hier und da mal was.

EDIT: Nachdem ich ja mit Timestamps arbeite, muss ich nicht current_date zu einer timestamp machen, sondern eben now()
 
hatte da einen Denkfehler dabei, weil wenn ich now()::timestamp in die Function einbaue, ist das ja kein Parameter, den ich angebe ;)
mal eben das ganze umschreiben :D
 
Just 4 Info hier, bevor ich einen neuen Thread aufmache:

Es ist mir sogar gelungen, die Maschine für eine zukünftige Mietung so rauszusuchen, die gerade nicht verwendet wird.

Code:
CREATE FUNCTION freie_maschinen_id_nach_name_zu_zeitpunkt (x text, y timestamp) RETURNS integer AS 'select maschinen_id from maschinen where maschinen_name = x
except select maschinen_id from vermietungen where mietzeit @> y' LANGUAGE sql STRICT IMMUTABLE;

Habe hierzu aber eine Frage:
Ich habe probiert, ob es funktioniert, es gab am Anfang Maschinen_ID 4 aus, wie ich nach "Normaler" gesucht habe, und dem momentamen Zeitpunkt.
Funktioniert das Ganze auch in die verkehrte Richtung? Sprich, weil der default-Wert hat bei mir 2 Stunden, dass jemand eine Maschine ab dem Zeitpunkt 2 Stunden vor der nächsten Miete mietet?

Anmerkung:
Ich bin neu geboren, weil ich wirklich Spaß am Ganzen habe :D

Arbeite mit OpenOffice als GUI-Programm, und es scheint soweit einwandfrei zu funktionieren ;)

EDIT: Frage selbst beantwortet, ja, es funktioniert ;)
 
"An IMMUTABLE function cannot modify the database and is guaranteed to return the same results given the same arguments forever."

Das dürfte nicht der Fall sein bei Dir. Darauf hatte ich Dich aber schon einmal hingewiesen. Noch einmal mache ich es nicht ...
 
Volatile wäre richtig, weil die Maschine frei werden könnte?

EDIT: hat wohl auch mit meiner Faulheit zu tun, ich speichere mir funktionierende Codes in eine Tabellen-Datei, und kopiere mir die schnell in den PGAdmin, verändere sie, und drücke auf ausführen ^^

Function mal eben auf Volatile geändert, und sache erledigt, danke für den Hinweis :D
Wird noch nicht in der Praxis angewendet (somit noch nicht den Test bestanden), aber ja, alle Fehler vorher ausbessern ;)
 
Zuletzt bearbeitet:
allgemeine Regel: definiere Funktionen immer als VOLATILE. Immer. Das ist auch der Default. Wenn Du solch eine Funktion in einem Index brauchst, dann muß sie IMMUTABLE sein. Dann, und erst dann, prüfe, ob sie das ist. "An IMMUTABLE function ... is guaranteed to return the same results given the same arguments forever.". Das ist eine Funktion, deren Resultat von der Abfrage einer oder mehrere Tabellen abhängig ist, NIE.
 
Was sollte ich unter "Index" verstehen?

Bin zwar nicht vom Storch gebracht worden, aber ab und an, muss ich doch nachfragen :X

Alle selbst erstellten Functions mal durchgegangen und auf Volatile geändert ;)
 
Zuletzt bearbeitet:
Werbung:
also sozusagen das Inhaltsverzeichniss einer Datenbank? :)

Ich glaube, das Thema Datenbanken beschleunigen wird für meine Anwendung nie eintreten.
es sei denn, das ganze kommt ernsthaft mal online (online für mietung eintragen, und etc...)
 
Zurück
Oben