触发检查两个字段的组合是否存在
Trigger to check if the combination of two field exist
我想创建一个触发器来检查我的放映时间和电影院 ID 是否存在。这将阻止我在两个相同的放映时间预订一个电影院。
其次,在此触发器中,我还检查我分配给电影的放映时间是否在电影发行和最后日期范围内。
但我不知道为什么 none 的声明有效。
Create table Movie([Movie_ID] int primary key not null,[Movie_Name] varchar(50) Unique not null,[Realease_Date] date not Null,[Last_Date] date,Runtime time(0) not null ,Status varchar(20) not null,Rating float)
Create table [Showtime]([Showtime_ID] int primary key not null,Date date not null,Time time(0) not Null)
Create table [Cinema Halls]([Cinema_Halls_ID] int primary key not null,[Total_Seats] int not Null)
Create table [Movie Schedule] (
[Movie_Schedule_ID] int primary key not null,
[Movie_ID] int NOT null,
[Showtime_ID] int not null,
Cinema_Halls_ID int not null
Constraint fk_M_ID FOREIGN KEY ([Movie_ID]) REFERENCES Movie([Movie_ID]),
Constraint fk_Sh_ID FOREIGN KEY ([Showtime_ID]) REFERENCES Showtime([Showtime_ID]),
Constraint fk_C_ID FOREIGN KEY ([Cinema_Halls_ID]) REFERENCES [Cinema Halls] ([Cinema_Halls_ID])
)
/*Trigger Stops duplicate booking of Cinema halls and invalid showtime of movie*/
Create Trigger Trigger_Movie_Shedule
On "Movie Schedule"
After Insert,Update
As
declare @Cinema_Halls_ID int ,@Showtime_ID int,@Movie_ID int,@Release_Date Date,@Last_Date Date, @Showtime_Date date;
Select @Cinema_Halls_ID =Cinema_Halls_ID from inserted ;
Select @Showtime_ID=Showtime_ID from inserted;
Select @Movie_ID=Movie_ID from inserted;
Select Showtime_Date=Date from Showtime where Showtime_ID=@Showtime_ID
Select @Release_Date= Release_Date from Movie where Movie_ID=@Movie_ID;
Select @Last_Date=Last_Date from Movie where Movie_ID=@Movie_ID;
IF EXISTS (select count (Showtime_ID) from "Movie Schedule"
where Showtime_ID = @Showtime_ID and Cinema_Halls_ID = @Cinema_Halls_ID )
BEGIN
PRINT'This Cinema Hall is Already Booked'
Rollback Transaction;
return
END
ELSE IF (@Showtime_DATE >= @Release_Date and @Showtime_Date<= @Last_Date)
BEGIN
PRINT'Movie Showtime not in Range'
Rollback Transaction;
return
END
我想这就是您要找的。 changes/improvements/best 做法是:
- 使用基于集合的逻辑,您应该始终致力于在关系数据库中这样做。
- 将
Inserted
用作 table 而不是单行
- 分号行终止符
set nocount on
- 使用
throw
- 使用
[]
而不是 ""
- 修复了“范围内”逻辑和重复逻辑检测
CREATE TRIGGER Trigger_Movie_Shedule
ON [Movie Schedule]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT 1
FROM [Movie Schedule] S
-- Restrict the check to the inserted/updated records
INNER JOIN Inserted I on I.Showtime_ID = S.Showtime_ID and I.Cinema_Halls_ID = S.Cinema_Halls_ID
GROUP BY S.Showtime_ID, S.Cinema_Halls_ID
-- If more than one row exists we have a problem Houston
HAVING COUNT(*) > 1
) BEGIN
-- Rolls back, returns and provides an error message all in one.
THROW 51000, 'This Cinema Hall is Already Booked',1;
END; ELSE IF EXISTS (
SELECT 1
FROM Inserted I
INNER JOIN Movie M ON M.Movie_ID = I.Movie_ID
INNER JOIN ShowTime S ON S.ShowTime_ID = I.ShowTime_ID
-- WHERE S.Showtime_DATE >= M.Release_Date and S.Showtime_Date < M.Last_Date
-- Think you logic detects when it *is* in range, whereas the error is when its out of range
WHERE S.Showtime_DATE < M.Release_Date or S.Showtime_Date > M.Last_Date
) BEGIN
-- Rolls back, returns and provides an error message all in one.
THROW 51000, 'Movie Showtime not in Range',1;
END;
END;
注意:我高度推荐阅读Using Inserted and Deleted,因为它非常清楚地解释了如何编写触发器。
我想创建一个触发器来检查我的放映时间和电影院 ID 是否存在。这将阻止我在两个相同的放映时间预订一个电影院。 其次,在此触发器中,我还检查我分配给电影的放映时间是否在电影发行和最后日期范围内。 但我不知道为什么 none 的声明有效。
Create table Movie([Movie_ID] int primary key not null,[Movie_Name] varchar(50) Unique not null,[Realease_Date] date not Null,[Last_Date] date,Runtime time(0) not null ,Status varchar(20) not null,Rating float)
Create table [Showtime]([Showtime_ID] int primary key not null,Date date not null,Time time(0) not Null)
Create table [Cinema Halls]([Cinema_Halls_ID] int primary key not null,[Total_Seats] int not Null)
Create table [Movie Schedule] (
[Movie_Schedule_ID] int primary key not null,
[Movie_ID] int NOT null,
[Showtime_ID] int not null,
Cinema_Halls_ID int not null
Constraint fk_M_ID FOREIGN KEY ([Movie_ID]) REFERENCES Movie([Movie_ID]),
Constraint fk_Sh_ID FOREIGN KEY ([Showtime_ID]) REFERENCES Showtime([Showtime_ID]),
Constraint fk_C_ID FOREIGN KEY ([Cinema_Halls_ID]) REFERENCES [Cinema Halls] ([Cinema_Halls_ID])
)
/*Trigger Stops duplicate booking of Cinema halls and invalid showtime of movie*/
Create Trigger Trigger_Movie_Shedule
On "Movie Schedule"
After Insert,Update
As
declare @Cinema_Halls_ID int ,@Showtime_ID int,@Movie_ID int,@Release_Date Date,@Last_Date Date, @Showtime_Date date;
Select @Cinema_Halls_ID =Cinema_Halls_ID from inserted ;
Select @Showtime_ID=Showtime_ID from inserted;
Select @Movie_ID=Movie_ID from inserted;
Select Showtime_Date=Date from Showtime where Showtime_ID=@Showtime_ID
Select @Release_Date= Release_Date from Movie where Movie_ID=@Movie_ID;
Select @Last_Date=Last_Date from Movie where Movie_ID=@Movie_ID;
IF EXISTS (select count (Showtime_ID) from "Movie Schedule"
where Showtime_ID = @Showtime_ID and Cinema_Halls_ID = @Cinema_Halls_ID )
BEGIN
PRINT'This Cinema Hall is Already Booked'
Rollback Transaction;
return
END
ELSE IF (@Showtime_DATE >= @Release_Date and @Showtime_Date<= @Last_Date)
BEGIN
PRINT'Movie Showtime not in Range'
Rollback Transaction;
return
END
我想这就是您要找的。 changes/improvements/best 做法是:
- 使用基于集合的逻辑,您应该始终致力于在关系数据库中这样做。
- 将
Inserted
用作 table 而不是单行 - 分号行终止符
set nocount on
- 使用
throw
- 使用
[]
而不是""
- 修复了“范围内”逻辑和重复逻辑检测
CREATE TRIGGER Trigger_Movie_Shedule
ON [Movie Schedule]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT 1
FROM [Movie Schedule] S
-- Restrict the check to the inserted/updated records
INNER JOIN Inserted I on I.Showtime_ID = S.Showtime_ID and I.Cinema_Halls_ID = S.Cinema_Halls_ID
GROUP BY S.Showtime_ID, S.Cinema_Halls_ID
-- If more than one row exists we have a problem Houston
HAVING COUNT(*) > 1
) BEGIN
-- Rolls back, returns and provides an error message all in one.
THROW 51000, 'This Cinema Hall is Already Booked',1;
END; ELSE IF EXISTS (
SELECT 1
FROM Inserted I
INNER JOIN Movie M ON M.Movie_ID = I.Movie_ID
INNER JOIN ShowTime S ON S.ShowTime_ID = I.ShowTime_ID
-- WHERE S.Showtime_DATE >= M.Release_Date and S.Showtime_Date < M.Last_Date
-- Think you logic detects when it *is* in range, whereas the error is when its out of range
WHERE S.Showtime_DATE < M.Release_Date or S.Showtime_Date > M.Last_Date
) BEGIN
-- Rolls back, returns and provides an error message all in one.
THROW 51000, 'Movie Showtime not in Range',1;
END;
END;
注意:我高度推荐阅读Using Inserted and Deleted,因为它非常清楚地解释了如何编写触发器。