2012-08-08 99 views
2

我正在尝试创建一个相当简单的触发器,它将一列添加到跟踪类似于Netflix的电影发行公司的租借数量的列中。SQL Server触发器:多部分标识符无法绑定

我关注的列是:

  • 电影movie_id, movie_title, release_year, num_rentals
  • Customer_rentalsitem_rental_id, movie_id, rental_date_out, rental_date_returned

我当前触发看起来是这样的:

CREATE TRIGGER tr_num_rented_insert 
ON customer_rentals FOR INSERT 
AS 
BEGIN 
UPDATE movies 
SET num_rentals=num_rentals+1 
WHERE customer_rentals.movie_id=movies.movie_id; 
END; 

它会返回错误:

Msg 4104, Level 16, State 1, Procedure tr_num_rented_insert, Line 7
The multi-part identifier "customer_rentals.movie_id" could not be bound.

我只是希望它匹配movie_id的,并添加1〜出租数量。

回答

6

你需要加入到inserted伪表:

CREATE TRIGGER dbo.tr_num_rented_insert 
ON dbo.customer_rentals 
FOR INSERT 
AS 
BEGIN 
    UPDATE m 
    SET num_rentals = num_rentals + 1 
    FROM dbo.movies AS m 
    INNER JOIN inserted AS i 
    ON m.movie_id = i.movie_id; 
END 
GO 

但我要问,什么是保持这个计数最新的电影表的意义呢?你可以随时看到查询计数,而不是将其存储冗余的:

SELECT m.movie_id, COALESCE(COUNT(r.movie_id)) 
    FROM dbo.moves AS m 
    LEFT OUTER JOIN dbo.customer_rentals AS r 
    ON m.movie_id = r.movie_id 
    GROUP BY m.movie_id; 

如果该查询的性能就成了一个问题,您可以创建一个索引视图来维持数量,使得你不必保持最新的一个触发:

CREATE VIEW dbo.rental_counts 
WITH SCHEMABINDING 
AS 
    SELECT movie_id, num_rentals = COUNT_BIG(*) 
    FROM dbo.customer_rentals 
    GROUP BY movie_id; 

这将导致维修为您的触发相同那种,但是它没有你的触发器,并执行它,而不会影响movies表。我们得到的租金计数你可以说:

SELECT m.movie_id, m.other_columns, 
    num_rentals = COALESCE(r.num_rentals, 0) 
    FROM dbo.movies AS m 
    LEFT OUTER JOIN dbo.rental_counts AS r 
    ON m.movie_id = r.movie_id; 

(我们使用一个离开,因为一部电影可能还没有被租在这里加入。)

这里有一个额外的好处是,你不必须执行任何技巧才能将电影表中的其他列转换为结果。它还可以确保数据的准确性,即使租赁被删除(您的触发器将继续愉快地为计数添加+1)。

+0

这是一个任务,我试图通过 - 参数是一个新插入的列(num_rentals),它必须增加每个租赁...我同意可以有更简单的方法来做到这一点。感谢您的帮助。修正它吧! – 2012-08-08 19:17:24

-1

您的代码对于简单的插入触发器是正确的。假设这两列确实存在于这两个表中,那么您的问题可能是您在WHERE语句末尾添加了分号。分号只能在END语句之后。

相关问题