插入,更新触发器检查日期是否重叠

时间:2017-03-10 11:36:35

标签: sql sql-server sql-server-2008

我有两张桌子:

CREATE TABLE Flight (
  flightnumber         INT                  NOT NULL,
  departuretime        DATETIME             NOT NULL,
  arrivaltime          DATETIME             NOT NULL,
)

CREATE TABLE PassengerForFlight (
  passengernumber      INT                  NOT NULL,
  flightnummer         INT                  NOT NULL,
)

现在我想写一个检查 PassengerForFlight 的触发器:如果乘客没有在重叠日期预订航班。

我的查询尝试:

SELECT *
FROM PassengerForFlight PV inner join FlightV ON PV.flightnumber=   V.flightnumber
WHERE PV.passengernumber = (SELECT passengernumber
                            FROM Inserted I) 
                            AND EXISTS(SELECT 1
                                      FROM Flight V1
                                      WHERE V.departuretime BETWEEN V1.departuretime AND V1.arrivaltime  
                                      OR V.arrivaltime  BETWEEN V1.departuretime AND V1.arrivaltime )

有人有想法吗?我无法弄清楚如何检查表中已存在数据的插入值

例如,我得到了这些数据:

Table Flight
INSERT Vlucht(flightnumber, depaturetime,arrivaltime)
  VALUES ( 5314,  '2004-01-30 11:30', '2004-02-01 11:30' );
INSERT Vlucht(flightnumber, depaturetime,arrivaltime)
  VALUES ( 5315,  '2004-01-31 11:30', '2004-02-02 11:30' );

Tabel PersonForFlight
INSERT PassengerForFlight(passengernumber,flightnummer) VALUES ( 850,  5314);

现在有了这些数据,我想为乘客数量850插入一个新航班

INSERT PassengerForFlight(passengernumber,flightnummer) VALUES ( 850,  5315);

这是必须的,因为5314和5315航班的时间与其他地方重叠

Thanx寻求帮助!

3 个答案:

答案 0 :(得分:1)

嗯,首先,你在表中缺少主键和外键 - 我会写这样的表:

CREATE TABLE Flight (
    flightnumber         INT                  NOT NULL,
    departuretime        DATETIME             NOT NULL,
    arrivaltime          DATETIME             NOT NULL,
    CONSTRAINT PK_Flight PRIMARY KEY (flightnumber)
);

CREATE TABLE PassengerForFlight (
    passengernumber      INT                  NOT NULL,
    flightnummer         INT                  NOT NULL 
    CONSTRAINT FK_PassengerForFlight_Flight FOREIGN KEY REFERENCES Flight(flightnumber),
    CONSTRAINT PK_PassengerForFlight PRIMARY KEY (passengernumber, flightnummer)
);

其次,您可以使用而不是插入触发器来处理同一个人的重叠航班:

CREATE TRIGGER tr_PassengerForFlight_IOI ON PassengerForFlight
INSTEAD OF INSERT
AS

    INSERT INTO PassengerForFlight (passengernumber, flightnummer)
    SELECT passengernumber, flightnummer
    FROM Inserted I
    INNER JOIN  Flight F1 ON I.flightnummer = F1.flightnumber
    WHERE NOT EXISTS
    (
        SELECT 1
        FROM PassengerForFlight P
        INNER JOIN Flight F2 ON P.flightnummer = F2.flightnumber
        WHERE P.passengernumber = I.passengernumber AND P.flightnummer <> I.flightnummer
        AND F2.departuretime <= F1.arrivaltime -- here is the test for overlapping dates
        AND F1.departuretime <= F2.arrivaltime -- here is the test for overlapping dates
    )

GO

为了测试触发器,我添加了另一个与现有航班不重叠的航班,并尝试将相同的乘客添加到所有3个航班:

INSERT INTO Flight (flightnumber, departuretime, arrivaltime) VALUES 
( 5314,  '2004-01-30 11:30', '2004-02-01 11:30' ),
( 5315,  '2004-01-31 11:30', '2004-02-02 11:30' ), 
( 5316,  '2004-02-03 11:30', '2004-02-05 11:30' );

INSERT INTO PassengerForFlight(passengernumber,flightnummer) VALUES ( 850,  5314);

请注意,下一个插入声明会尝试将相同的乘客编号插入2个不同的航班:

INSERT INTO PassengerForFlight(passengernumber,flightnummer) VALUES ( 850,  5315), ( 850,  5316);

测试:

SELECT *
FROM PassengerForFlight 

结果:

passengernumber flightnummer
850             5314
850             5316

答案 1 :(得分:0)

您想要考虑如何在发生之前避免插入而不是使用触发器。

这可以在您的UI中解决,但在后端您可以编写一些SQL并进行检查

IF NOT EXISTS (Check here if the passenger is booked on any flights that overlap the date) 
BEGIN
     INSERT PassengerForFlight(passengernumber,flightnummer) VALUES ( 850,  5315);
END

答案 2 :(得分:0)

我不确定如果有或没有重叠,您是否要返回结果。无论哪种方式,要检查重叠,通常需要一个where子句,如下所示:

WHERE
    flightA.DepartureTime < flightB.ArrivalTime AND
    flightA.ArrivalTime > flightB.DepartureTime