我试图在IF语句中比较触发器中的插入表。 在IF语句的第一个块中,我正在过滤插入的表,以便插入的电影室号码(filmzaal_zaalnummer)等于议程表中的电影室号码。
议程表给了我3列 1)电影室号码 2)电影的开始日期_时间 3)电影的结束日期_时间。
所以在我将agenda.filmzaal_zaalnummer与inserted.filmzaal_zaalnummer进行比较之后,我试图找出电影的插入开始日期_时间是否已经在议程上的电影的开始日期_时间和结束日期_时间之间。
我认为如果插入的开始date_time没有中断任何其他现有的电影我的SELECT TOP 1 inserted.id应该为空,这就是为什么我将它与最初插入的id进行比较,这样如果插入的议程正在中断任何现有的电影,IF语句将被激活并且应该击退回滚。 但现在我的触发器始终被激活。 我该如何解决这个问题?
ALTER TRIGGER [dbo].[trg_controlleer_afspeeldatum]
ON [dbo].[agenda]
AFTER INSERT
AS
BEGIN
if (
select top 1 i.id
from ( select filmzaal_zaalnummer, datum_tijd, DATEADD(minute,f.speelduur,datum_tijd) as eind_datum_tijd
from agenda a, film f
where a.film_titel = f.titel ) AS agenda,
inserted i
where i.filmzaal_zaalnummer = agenda.filmzaal_zaalnummer
and i.datum_tijd between agenda.datum_tijd and agenda.eind_datum_tijd
) =
(
select top 1 i.id
from inserted i
)
begin
rollback transaction
print 'Er draait dan al een film op die tijd in die zaal'
return
end
END
答案 0 :(得分:1)
首先是一些提示:
- 在所有代码中使用英语
- 给出数据库模式
- 创建脚本
- 给一些成功/失败的测试用例
- 用可理解的英语描述你想要完成的事情
代码中有两个问题:
1.在您的查询中,您正在查看已经列入议程的电影,因此总是存在重复。因此,只比较agenda.id<>inserted.id
的记录。见Use the inserted and deleted Tables:
insert表在INSERT期间存储受影响行的副本 和UPDATE语句。在插入或更新事务期间, new 行被添加到插入的表和触发器表。该 inserted表中的行是触发器中新行的副本 表。
这是正确的代码和一些测试用例:
drop trigger [trg_Check_Agenda_For_Double_Bookings];
go
create TRIGGER [trg_Check_Agenda_For_Double_Bookings]
ON agenda
after INSERT
AS
BEGIN
declare @count int;
set @count = (
select count(*) as countDuplicates
from (
select id,filmzaal_zaalnummer, datum_tijd, DATEADD(minute,f.speelduur,datum_tijd) as eind_datum_tijd
from agenda a, film f
where a.film_titel = f.titel) AS agenda, inserted i
where i.filmzaal_zaalnummer = agenda.filmzaal_zaalnummer
and i.id<>agenda.id
and i.datum_tijd between agenda.datum_tijd and agenda.eind_datum_tijd
)
if (@count>0)
begin
rollback transaction
print 'There is already a movie playing during the same time in that theatre.'
return
end
END;
go
delete from agenda
--must succeed (first planned movie in agenda)
INSERT [dbo].[agenda] ([film_titel], [filmzaal_zaalnummer], [datum_tijd] , [taalversie], [projectie]) VALUES
( N'Logan', 1, CAST(N'2017-01-01T00:00:00.000' AS DateTime), N'Engels', N'TweeD');
--must fail because Logan movie takes 137 minutes
INSERT [dbo].[agenda] ([film_titel], [filmzaal_zaalnummer], [datum_tijd] , [taalversie], [projectie]) VALUES
( N'Logan', 1, CAST(N'2017-01-01T01:00:00.000' AS DateTime), N'Engels', N'TweeD');
INSERT [dbo].[agenda] ([film_titel], [filmzaal_zaalnummer], [datum_tijd] , [taalversie], [projectie]) VALUES
( N'Logan', 1, CAST(N'2017-01-01T02:00:00.000' AS DateTime), N'Engels', N'TweeD');
--must succeed because this one is 3 hours later and Logan only takes 137 minutes
INSERT [dbo].[agenda] ([film_titel], [filmzaal_zaalnummer], [datum_tijd] , [taalversie], [projectie]) VALUES
( N'Logan', 1, CAST(N'2017-01-01T03:00:00.000' AS DateTime), N'Engels', N'TweeD');
--multi insert of a good and bad planned movie (above 2 records) but both will fail because whole transaction/insert will be rolled back!
INSERT [dbo].[agenda] ([film_titel], [filmzaal_zaalnummer], [datum_tijd] , [taalversie], [projectie]) VALUES
( N'Logan', 1, CAST(N'2017-01-01T02:00:00.000' AS DateTime), N'Engels', N'TweeD'),
( N'Logan', 1, CAST(N'2017-01-01T03:00:00.000' AS DateTime), N'Engels', N'TweeD');