2

Netflixに似た映画配給会社からのレンタル数を追跡する列にトリガーを追加する、かなり単純なトリガーを作成しようとしています。

私が焦点を当てている列は次のとおりです。

  • 映画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;

エラーを返します:

メッセージ4104、レベル16、状態1、プロシージャtr_num_rented_insert、7行目
マルチパート識別子「customer_rentals.movi​​e_id」をバインドできませんでした。

movie_idと一致させ、レンタル数に1を加えたいだけです。

4

2 に答える 2

7

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;

(映画がまだレンタルされていない可能性があるため、ここではLEFT JOINを使用します。)

ここでの追加のボーナスは、ムービーテーブルから結果に他の列を取得するためにトリックを実行する必要がないことです。また、レンタルが削除された場合でもデータが正確であることを保証します(トリガーはカウントに+1を追加し続けます)。

于 2012-08-08T19:02:44.953 に答える
-1

あなたのコードは単純な挿入トリガーに対して正しいです。これらの列が両方のテーブルに存在すると仮定すると、WHEREステートメントの最後にセミコロンを置くことが問題になる可能性があります。セミコロンは、ENDステートメントの後にのみ存在する必要があります。

于 2016-07-28T01:47:03.263 に答える