У нас есть DVD Прокат компании. В этом конкретном сценарии мы рассматриваем только таблицы «Участник», «Аренда» и «Членство».
Задача состоит в том, чтобы написать триггер, который предотвращает доставку клиентом DVD-диска, если он достиг месячного лимита на аренду DVD-дисков в соответствии с их членством. контракт с использованием функции.
Мой триггер приводит к бесконечному l oop. Он работает без Пока l oop, но тогда он не будет работать должным образом, если я рассмотрю несколько обновлений таблицы Rental. Где я не прав?
-- do not run, infinite loop
CREATE OR ALTER TRIGGER trg_Rental_StopDvdShip
ON RENTAL
FOR UPDATE
AS
BEGIN
DECLARE @MemberId INT
DECLARE @RentalId INT
SELECT * INTO #TempTable FROM inserted
WHILE (EXISTS (SELECT RentalId FROM #TempTable))
BEGIN
IF UPDATE(RentalShippedDate)
BEGIN
IF (SELECT TotalDvdLeft FROM dvd_numb_left(@MemberId)) <= 0
BEGIN
ROLLBACK
RAISERROR ('YOU HAVE REACHED MONTHLY LIMIT FOR DVD RENTALS', 16, 1)
END;
END;
DELETE FROM #TempTable WHERE RentalID = @RentalId
END;
END;
Моя функция выглядит следующим образом:
CREATE OR ALTER FUNCTION dvd_numb_left(@member_id INT)
RETURNS @tab_dvd_numb_left TABLE(MemberId INT, Name VARCHAR(50), TotalDvdLeft INT, AtTimeDvdLeft INT)
AS
BEGIN
DECLARE @name VARCHAR(50)
DECLARE @dvd_total_left INT
DECLARE @dvd_at_time_left INT
DECLARE @dvd_limit INT
DECLARE @dvd_rented INT
DECLARE @dvd_at_time INT
DECLARE @dvd_on_rent INT
SET @dvd_limit = (SELECT Membership.MembershipLimitPerMonth FROM Membership
WHERE Membership.MembershipId = (SELECT Member.MembershipId FROM Member WHERE Member.MemberId = @member_id))
SET @dvd_rented = (SELECT COUNT(Rental.MemberId) FROM Rental
WHERE CONCAT(month(Rental.RentalShippedDate), '.', year(Rental.RentalShippedDate)) = CONCAT(month(GETDATE()), '.', year(GETDATE())) AND Rental.MemberId = @member_id)
SET @dvd_at_time = (SELECT Membership.DVDAtTime FROM Membership
WHERE Membership.MembershipId = (SELECT Member.MembershipId FROM Member WHERE Member.MemberId = @member_id))
SET @dvd_on_rent = (SELECT COUNT(Rental.MemberId) FROM Rental
WHERE Rental.MemberId = @member_id AND Rental.RentalReturnedDate IS NULL)
SET @name = (SELECT CONCAT(Member.MemberFirstName, ' ', Member.MemberLastName) FROM Member WHERE Member.MemberId = @member_id)
SET @dvd_total_left = @dvd_limit - @dvd_rented
SET @dvd_at_time_left = @dvd_at_time - @dvd_on_rent
IF @dvd_total_left < 0
BEGIN
SET @dvd_total_left = 0
SET @dvd_at_time_left = 0
INSERT INTO @tab_dvd_numb_left(MemberId, Name, TotalDvdLeft, AtTimeDvdLeft)
VALUES(@member_id, @name, @dvd_total_left, @dvd_at_time_left)
RETURN;
END
INSERT INTO @tab_dvd_numb_left(MemberId, Name, TotalDvdLeft, AtTimeDvdLeft)
VALUES(@member_id, @name, @dvd_total_left, @dvd_at_time_left)
RETURN;
END;
Буду рад любым советам.