「ブロックバスターのような」映画会社のSQLサーバー更新トリガーを記述しようとしています。私のMOVIESテーブルには、PKとしてmovie_idがあり、映画がレンタルされた回数の合計を保持するnum_rentedという別の列があります。この合計は、挿入、削除、および更新トリガーを介して行われます。 (これを行うにははるかに良い方法があることを理解していますが、私の割り当てでは特にこれを求めているので、この点を理解してください)。 MOVIESのPKおよびmovie_idはFKであるため、CUSTOMER_RENTALSテーブルにはitem_rental_idがあります。
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列を以前の値に復元する必要があるのかと思っていますが、方法がわかりません。事前に10億に感謝します!
DMLステートメントは複数の行に影響を与える可能性があることを考慮する必要があります(この場合、INSERTED
およびDELETED
テーブルにも複数の行が含まれます)。
また、映画が別のIDに更新された場合(および新しい映画の数を増やす場合)、映画のレンタル数を減らす必要があることも考慮する必要があります。
以下は、挿入と削除のカウントを統合し、最終的な変更を関連する映画IDに適用します。
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;
私はあなたが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