7

「ブロックバスターのような」映画会社の SQL サーバー更新トリガーを作成しようとしています。MOVIES テーブルには、PK としての movie_id と、映画がレンタルされた回数の合計を保持する num_rented という別の列があります。この合計は、insert、delete、および update トリガーによって行われます。(これを行うためのはるかに良い方法があることは理解していますが、私の仕事は特にこれを必要としているので、この点を理解してください). CUSTOMER_RENTALS テーブルには PK として item_rental_id があり、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 列を以前の値に復元する必要があると考えていますが、方法がわかりません。事前に10億をありがとう!

4

3 に答える 3

10

DML ステートメントが複数の行に影響を与える可能性があることを考慮する必要があります (この場合、INSERTEDおよびDELETEDテーブルにも複数の行が含まれます。

また、映画が別の ID に更新された場合は (新しい映画の数を増やすだけでなく)、映画のレンタル数を減らす必要があることも考慮する必要があります。

以下は、挿入と削除からのカウントを統合し、関連するmovieidに正味の変更を適用します。

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; 
于 2015-04-06T14:25:44.887 に答える
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
于 2013-04-20T21:14:53.433 に答える
-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
于 2013-04-20T20:55:36.423 に答える