Skip to content
Advertisement

Trigger to check if the combination of two field exist

I want to create a trigger which will check if my showtime with Cinema Hall Id exist or not. This will prevent me from booking one Cinema hall at two same Showtimes. Secondly in this trigger I am also checking if the showtime I am assigning to movie lies in movie release and last date range or not. But I don’t know why none of the statement is working.

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

Advertisement

Answer

I think this is what you are looking for. The changes/improvements/best practices are:

  • Uses set-based logic, which you should always aim to do in a relational database.
  • Uses Inserted as a table rather than a single row
  • Semi-colon line terminators
  • set nocount on
  • Uses throw
  • Uses [] instead of ""
  • Fixed “in range” logic and detection of duplicate logic
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;

Note: I highly recommend reading Using Inserted and Deleted as it explains very clearly how to write triggers.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement