Sql Server Update触发器:如何使其工作

时间:2013-04-20 20:27:54

标签: sql sql-server triggers

我正在尝试为我的“Blockbuster-like”电影公司编写一个sql server更新触发器。在我的MOVIES表中,我将movie_id作为PK,另一列名为num_rented,它总共保留了一部电影的租借次数。这个总数是通过我的插入,删除和更新触发器完成的。 (我知道有更好的方法可以做到这一点,但我的任务特别要求这样做,所以请理解这一点)。 CUSTOMER_RENTALS表具有item_rental_id作为PK,MOVIES中的movie_id是FK。

我需要一个更新触发器,只要对CUSTOMER_RENTALS进行更新,它就会更新MOVIES中的num_rentals列。例如,假设movie_id 1已输入,但这是一个错误,它确实是movie_id 2.我希望num_rentals能够反映更新。

这是我到目前为止所做的,但我真的不知道在SET部分放置什么来实现这一目标:

CREATE TRIGGER tr_num_rentals_update
ON customer_rentals
AFTER UPDATE
AS
BEGIN
UPDATE m
SET num_rentals = ??????
FROM movies AS m
INNER JOIN inserted as i on m.movie_id=i.movie_id;
END;

我在想某种方式我需要访问已删除表的值以将num_rental列恢复为之前的值,但我不知道如何。提前感谢十亿!

3 个答案:

答案 0 :(得分:9)

您需要考虑DML语句可能会影响多行(在这种情况下,INSERTEDDELETED表也会有多行。

如果要更新为不同的ID(以及增加新电影的点数),您还需要考虑减少电影的租借数量。

下面合并插入和删除的计数,并将净更改应用于相关的movieids。

CREATE TRIGGER tr_num_rentals_update
ON customer_rentals
AFTER INSERT, UPDATE, DELETE
AS
  BEGIN
      IF UPDATE(movie_id) /*If column not affected skip*/
        BEGIN
            WITH T1(Cnt, movie_id)
                 AS (SELECT COUNT(*),
                            movie_id
                     FROM   inserted
                     GROUP  BY movie_id
                     UNION ALL
                     SELECT -COUNT(*), /*negative for deletes*/
                            movie_id
                     FROM   deleted
                     GROUP  BY movie_id),
                 T2
                 AS (SELECT SUM(Cnt) AS NetCnt,
                            movie_id
                     FROM   T1
                     GROUP  BY movie_id)
            UPDATE m
            SET    num_rentals = num_rentals + NetCnt
            FROM   movies AS m
                   INNER JOIN T2
                     ON m.movie_id = T2.movie_id;
        END
  END; 

答案 1 :(得分:1)

我相信你可以通过添加m.num_rentals + 1

来实现这一目标

还要为已删除的

添加更新声明
UPDATE M
SET num_rentals = m.numrentals - 1
FROM
Movies M
INNER JOIN Deleted D ON
M.movie_id = D.Movie_ID

然而,我宁愿创建一个应用程序可以用来选择它的视图,而不是在触发器中使用它。因此,删除每次更新时需要执行的额外数据处理,插入和删除

CREATE VIEW MoviesVW AS
SELECT M.Movie_ID, COUNT(R.*) AS Num_Rental
FROM Movies M
LEFT JOIN customer_rentals R ON
R.movies_id = M.movies_ID
GROUP BY
M.Movie_ID

答案 2 :(得分:-1)

您需要在更新触发后执行。您可以尝试以下方法。为了更好地理解触发器,我强烈推荐这个链接 http://www.codeproject.com/Articles/25600/Triggers-Sql-Server

CREATE TRIGGER trgAfterUpdate ON [dbo].[customer_rentals] 
FOR UPDATE
AS
    declare @num_rentals int;
    declare @movie_id int;

    SELECT @movie_id =i.movie_id from inserted i;   
    SELECT @num_rentals =num_rentals from MOVIES where movie_id =@movie_id 
    SET @num_rentals =@num_rentals +1;

      -- perform update here in movies table    

    UPDATE MOVIES SET num_rentals=@num_rentals WHERE movie_id =@movie_id 

GO