j r*_*j r 2 sql sql-server triggers identifier
我正在尝试创建一个相当简单的触发器,它会在一个列中添加一个触发器来跟踪类似于Netflix的电影发行公司的租借数量.
我关注的专栏是:
movie_id, movie_title, release_year, num_rentals)item_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;
Run Code Online (Sandbox Code Playgroud)
它返回错误:
消息4104,级别16,状态1,过程tr_num_rented_insert,第7行
无法绑定多部分标识符"customer_rentals.movie_id".
我只是希望它与movie_id匹配,并将1添加到租借数量.
您需要加入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
Run Code Online (Sandbox Code Playgroud)
但我不得不问,在电影表中保持最新状态有什么意义?您始终可以在查询中获取计数,而不是冗余地存储它:
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;
Run Code Online (Sandbox Code Playgroud)
如果该查询的性能成为问题,您可以创建一个索引视图来维护计数,这样您就不必使用触发器使其保持最新:
CREATE VIEW dbo.rental_counts
WITH SCHEMABINDING
AS
SELECT movie_id, num_rentals = COUNT_BIG(*)
FROM dbo.customer_rentals
GROUP BY movie_id;
Run Code Online (Sandbox Code Playgroud)
这将导致同一类型的维护,你的触发,但是它没有你的触发器,并执行它,而不会影响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;
Run Code Online (Sandbox Code Playgroud)
(我们在这里使用LEFT JOIN,因为电影可能尚未租用.)
此处的另一个好处是,您无需执行任何技巧即可将电影表中的其他列添加到结果中.即使租约被删除,它也可确保数据准确无误(您的触发器将继续愉快地为计数添加+1).
| 归档时间: |
|
| 查看次数: |
5606 次 |
| 最近记录: |