我是SQL Server的新手并做作业。
我有一张表Booking_Details(Booking_ID,Date_From,Date_To,Room_Number,Hotel_ID)
我想在插入或更新数据库之前创建一个触发器来比较Date_From和Date_to。我正在尝试像这样的触发器
CREATE TRIGGER check_date ON Booking_Details
FOR UPDATE, INSERT
AS
IF (UPDATE(Date_To) OR UPDATE(Date_From))
BEGIN
DECLARE @Date_From DATE, @Date_To DATE
SET @Date_From=(SELECT Date_From FROM Booking_Details)
SET @Date_To=(SELECT Date_To FROM Booking_Details)
IF(@Date_From>@Date_To)
BEGIN
PRINT "Date To must larger than Date From"
END
END
但是当我测试它时返回
子查询返回的值超过1。这是不允许的 子查询跟随=,!=,<,< =,>,> =或当子查询用作 表达。
答案 0 :(得分:3)
有几个缺陷......
你必须改变这个
SET @Date_From=(SELECT Date_From FROM Booking_Details)
SET @Date_To=(SELECT Date_To FROM Booking_Details)
到这个
SET @Date_From=(SELECT Date_From FROM inserted)
SET @Date_To=(SELECT Date_To FROM inserted)
表'inserted'是一个结构相同的“表”,包含实际过程的行。
您尝试使用=(SELECT Date_From FROM inserted)
设置变量的值只能使用一行!
您必须意识到,触发器必须能够同时处理多个行。如果您插入或更新多行,则此方法会中断...
您是否可以使用CHECK CONSTRAINT
代替此触发器?这会容易得多......
可能有点简单:
CREATE TRIGGER check_date ON Booking_Details
FOR UPDATE, INSERT
AS
BEGIN
IF (UPDATE(Date_To) OR UPDATE(Date_From)) AND EXISTS(SELECT 1 FROM inserted WHERE Date_From>DateTo)
--Do something (I'd suggest RAISERROR)
END
IF EXISTS(SELECT ...)
将为true,如果任何插入/更新的行无效。你甚至可以让(UPDATE(Date_To) OR UPDATE(Date_From))
离开......
关于RAISERROR
find details here