2017-05-31 2 views
1

Hallo für Hobbyzwecke ich versuche, eine C# -Anwendung mit einer MS SQL Server-Datenbank, die ein Hotel-System wieder zusammensetzt erstellen. Ich versuche nun, einen SQL-Trigger zu erstellen, der eine Datumsdifferenz berechnet. Eine Reservierung darf nicht länger als 6 Wochen (42 Tage) sein. Allerdings löst mein Auslöser auch bei Reservierungen aus, die eine Abweichung von weniger als 42 Tagen haben, auch wenn die Differenz 1 Tag beträgt. also bin ich mir nicht sicher, was ich falsch mache.Trigger, der datediff

Meine Trigger:

create trigger trigger_reservation 
on reservation 
after update, insert 
as 
if exists 
(
select reservationid, DATEDIFF(dd,Startdate,Enddate) 
from reservation 
group by reservationid, enddate, startdate 
having DATEDIFF(dd,Startdate,Enddate) > 42 
) 
begin 
    raiserror('Error: Reservation may not be longer than 6 weeks',16, 1) 
    rollback transaction 
end 
+0

Sicherlich überprüft Ihr Auslöser die GESAMTE Tabelle und nicht nur die Zeile, die Sie einfügen? Wenn Sie in der Datentabelle bereits eine Reservierung von mehr als 42 Tagen haben, wird der Trigger immer ausgelöst. –

+0

Sie haben recht, es gibt in der Tat einige Reservierungen, die länger als 42 Tage sind (zufällig generierte Daten). Wie würde ich das beheben? – glnxhjeh

+0

Grundsätzlich müssen Sie über die "speziellen" Tabellen wissen, auf die Sie in einem Trigger zugreifen können, der hier "eingefügt" werden soll. Ich sehe, dass Peterm seine Antwort aktualisiert hat, und das sollte genau so funktionieren, wie Sie es benötigen ... –

Antwort

3

Trigger sind teuer zu betreiben und zu warten. Diese Art der Überprüfung kann hier durch eine einfache CHECK CONSTRAINT

CREATE TABLE reservation (
    reservationid INT, 
    startdate DATE, 
    enddate DATE, 
    -- ... 
    CONSTRAINT reservation_dates_ck 
    CHECK(DATEDIFF(dd, startdate, enddate) < 43) 
) 

erreicht werden, ist eine dbfiddle Demo

Und hier ist, wie Sie gehen über die es mit einem Trigger

CREATE TRIGGER trigger_reservation 
ON reservation AFTER UPDATE, INSERT 
AS 
    IF EXISTS (
    SELECT * 
     FROM inserted 
    WHERE DATEDIFF(dd, startdate, enddate) > 42 
) 
    BEGIN 
    RAISERROR ('Error: Reservation may not be longer than 6 weeks', 16, 1); 
    ROLLBACK TRANSACTION; 
    RETURN 
END; 

hier tun, ist ein dbfiddle Demo

+0

Danke für die Antwort. Ich weiß über Schecks, aber zu Testzwecken möchte ich wirklich, dass es ein Auslöser ist. – glnxhjeh

+0

Siehe die aktualisierte Antwort – peterm

+0

Die Check-Einschränkung ist der beste Weg, um dies zu umgehen. Die Verwendung eines Triggers ist hier vergleichbar mit der Verwendung eines Cursors, wenn eine Set-basierte Lösung verfügbar ist. –