![]() |
Datenbank: FB • Version: 2 • Zugriff über: egal
FB: keine Datums-Zeitraum-Überlappung
Hallo #,
in einer Tabelle speichere ich Datensätze Id Integer (PrimKey) StartDate Date EndDate Date StartDate/EndDate definieren Zeiträume. Ich möchte verhindern, dass überlappende Zeiträume gespeichert werden. Erlaubt ist 1.1.2009-5.1.2009 6.1.2009-9.1.2009 Nicht erlaubt 1.1.2009-5.1.2009 5.1.2009-9.1.2009 oder 1.1.2009-5.1.2009 4.1.2009-9.1.2009 Bekomme ich das irgendwie in der DB hin, Index geht wohl nicht Check-Constraint ? Mir wäre aber ein Constraint lieber. Was kann ich hier machen ? Danke Heiko |
Re: FB: keine Datums-Zeitraum-Überlappung
SQL-Code:
CREATE TABLE tabelle (
id INT, von DATE, bis DATE, CONSTRAINT PK_tabelle PRIMARY KEY (id), CONSTRAINT CK_tabelle CHECK (NOT EXISTS (SELECT * FROM tabelle WHERE new.von <= bis AND new.bis >= von)) ); |
Re: FB: keine Datums-Zeitraum-Überlappung
Das Select in CK_tabelle findet nur Datensätze, die in der aktiven Transaktion sichtbar sind.
Deshalb ist es im Ausnahmefall doch noch möglich überschneidende Zeiträume zu erfassen:
Code:
Transaction1.Start;
Transaction2.Start; innerhalb von Transaktion1: insert into tabelle (id, von, bis) values (1, '01.01.2009', '31.12.2009'); Transaction1.Commit; innerhalb von Transaktion2: insert into tabelle (id, von, bis) values (2, '01.01.2009', '31.12.2009'); Transaction2.Commit; |
Re: FB: keine Datums-Zeitraum-Überlappung
Hallo,
*seufz* siehe auch ![]() Und wie sollte man das dann machen ? Ich befürchte, "Ich sperre, also bin ich", muss ich wieder benutzen. Heiko |
Re: FB: keine Datums-Zeitraum-Überlappung
Eine Möglichkeit wäre, den Schreibzugriff nur einer Transaktion zu gestatten:
SQL-Code:
Wenn erforderlich auch im "Before Update".
CREATE TABLE T_LOCK (
LOCKEVENT VARCHAR(40) NOT NULL ); ALTER TABLE T_LOCK ADD CONSTRAINT PK_LOCK PRIMARY KEY (LOCKEVENT); SET TERM ^ ; create procedure P_LOCK ( LOCKEVENT varchar(40)) as declare variable CNT integer; begin /* Aktion für andere Transaktionen sperren */ select count(lockevent) from t_lock where lockevent = :lockevent into cnt; if (cnt = 0) then begin insert into t_lock (lockevent) values (:lockevent); end else begin update t_lock set lockevent = :lockevent where lockevent = :lockevent; end end^ CREATE TRIGGER R_TABELLE_BI FOR T_TABELLE ACTIVE BEFORE INSERT POSITION 0 as begin /* Zugriff auf Tabelle für andere Transaktionen sperren */ execute procedure p_lock ('T_TABELLE'); end ^ SET TERM ; ^ |
Re: FB: keine Datums-Zeitraum-Überlappung
Hallo,
verstanden habe ich das jetzt nicht so richtig ;) Aber: Was passiert, wenn mal "was schiefgeht", d.h. in der Lock-Table steht aus Versehen noch was drin. Das kommt jetzt schon dem "Ich sperre, also bin ich" nahe. Ich glaube FB 2.1 hat da mit GTT (global temp table) sogar was drin, was den Eintrag nach Abschluss der Transaktion wieder löscht. Danke Heiko |
Re: FB: keine Datums-Zeitraum-Überlappung
In der Lock-Tabelle steht immer was drin, das heist es wird nichts gelöscht.
Das Dummy-Update kann für einen bestimmten Datensatz nur einmal gemacht werden (jeder Datensatz repräsentiert eine Tabelle oder ein anderes Objekt das geschützt werden soll). So lange die Transaktion noch läuft, kann innerhalb einer anderen Transaktion der selbe Datensatz in T_LOCK nicht verändert werden. Der Trigger feuert in der ersten Transaktion, die einen Datensatz einfügt. So lange diese Transaktion nicht beendet wurde, wird jeder weitere Versuch einen Datensatz einzufügen scheitern. |
Re: FB: keine Datums-Zeitraum-Überlappung
Hallo,
so langsam begreife ich. OK. Aber geht das nicht auch anders, aud DDL-Ebene ? Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz