2015-01-21 88 views
0

我被困在这个问题上,我想防止发生重复预订。这是我一直在使用的代码:防止SQL中的重复预订

USE INL5 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[trg_bookinginfo_doublebooking] ON [dbo].[bookinginfo] 
FOR INSERT AS 
DECLARE @startdate AS DATE 
DECLARE @enddate AS DATE 
DECLARE @roomnumber AS CHAR(3) 

SELECT @startdate = inserted.startdate, @enddate = inserted.enddate, @roomnumber = inserted.roomnumber 
FROM inserted, bookinginfo 
WHERE @roomnumber = bookinginfo.roomnumber AND (@startdate BETWEEN bookinginfo.startdate AND bookinginfo.enddate) AND (@enddate BETWEEN bookinginfo.startdate AND bookinginfo.enddate) 
IF EXISTS(SELECT * FROM inserted) 

BEGIN RAISERROR ('Double bookings are not allowed',16,1) 
ROLLBACK TRANSACTION 
END 

的问题是,错误发生的日期是否被重叠。我究竟做错了什么?

回答

5

本声明:

SELECT @startdate = inserted.startdate, @enddate = inserted.enddate, 
     @roomnumber = inserted.roomnumber 
FROM inserted, bookinginfo 
WHERE @roomnumber = bookinginfo.roomnumber AND 
    (@startdate BETWEEN bookinginfo.startdate AND bookinginfo.enddate) AND 
    (@enddate BETWEEN bookinginfo.startdate AND bookinginfo.enddate) 

高度嫌疑。您正在分配select中的变量并在where中使用相同的变量。将此表示为正常join有问题吗?

SELECT @startdate = i.startdate, @enddate = i.enddate, @roomnumber = i.roomnumber 
FROM inserted i JOIN 
    bookinginfo bi 
    ON i.roomnumber = bi.roomnumber AND 
     (i.startdate BETWEEN bi.startdate AND bi.enddate) AND 
     (i.enddate BETWEEN bi.startdate AND bi.enddate) AND 
     i.BookinginfoID <> bi.BookinginfoID; 

这仍然没有做你想要的,有两个原因。首先,这个逻辑是不正确的。而且,if甚至没有使用它。我认为以下是你想要的触发器的身体:

IF (EXISTS (SELECT 1 
      FROM inserted i JOIN 
       bookinginfo bi 
       ON i.roomnumber = bi.roomnumber AND 
        i.startdate <= bi.enddate AND 
        i.enddate >= bi.startdate AND 
        i.BookinginfoID <> bi.BookinginfoID; 
      ) 
BEGIN 
    RAISERROR ('Double bookings are not allowed',16,1) 
    . . . 
END; 
+0

我试过最后一部分,但它仍然无法正常工作。现在的问题是,双重预订不会发生任何错误。你知道这可能是什么原因吗? – user3428812 2015-01-21 12:50:01

+0

我通过在instnddate> = bi.startdate之后将ON.BookinginfoID <> bi.BookinginfoID添加到ON语句来解决此问题。谢谢您的帮助。 – user3428812 2015-01-21 13:20:24

+0

@ user3428812。 。 。是的,这也是绝对需要的。 – 2015-01-21 20:51:18

0

这是因为最后的IF EXISTS(SELECT * FROM inserted)。 U没有在选定的值之前检查,只是每个没有提及的值。它总是会回报你。

应该看起来像:

USE INL5 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[trg_bookinginfo_doublebooking] ON [dbo].[bookinginfo] 
FOR INSERT AS 
DECLARE @startdate AS DATE 
DECLARE @enddate AS DATE 
DECLARE @roomnumber AS CHAR(3) 

IF EXISTS(SELECT @startdate = inserted.startdate, @enddate = inserted.enddate, @roomnumber = inserted.roomnumber 
FROM inserted, bookinginfo 
WHERE @roomnumber = bookinginfo.roomnumber AND (@startdate BETWEEN bookinginfo.startdate AND bookinginfo.enddate) AND (@enddate BETWEEN bookinginfo.startdate AND bookinginfo.enddate)) 

BEGIN RAISERROR ('Double bookings are not allowed',16,1) 
ROLLBACK TRANSACTION 
END