2013-04-20 17 views
6

"Blockbuster-like" film şirketim için bir sql server update tetikleyicisi yazmaya çalışıyorum. Benim MOVIES tablosumda, bir filmin kaç kez kiralandığını toplam olarak tutar. Bu toplam ekleme, silme ve tetikleyicileri güncelleme yoluyla yapılır. (Bunu yapmanın çok daha iyi yollarının olduğunu anlıyorum, ancak ödevlerim bunu özellikle istiyor, bu yüzden lütfen bu noktayı anlayın). CUSTOMER_RENTALS tablosu, PK olarak item_rental_id, MOVIES'den film_id ise bir FK'dir.Sql Sunucu Güncelleştirmesi tetikleyicisi: Nasıl çalışır?

CUSTOMER_RENTALS için bir güncelleme yapıldığında, MOVIES'deki num_rentals sütununu güncelleyecek bir güncelleştirme tetikleyicisine ihtiyacım var. Örneğin, movie_id 1 girdiyse ancak bu bir hataydı ve gerçekten de film_id 2 idi. Num_rentals'ın güncellemeyi yansıtmasını isterdim. Ben silinmiş tablonun değerlerini erişmesi gereken şekilde düşünüyorum

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; 

: Burada

var bugüne kadar ama gerçekten bunu gerçekleştirmek için SET kısmında koymak için bilmiyorum ne num_rental sütunu önceki değerine geri yüklerim ama nasıl yapacağımı bilmiyorum. Şimdiden bir milyar teşekkür!

+0

Yapabileceğiniz 'SET num_rentals = num_rentals + Güncelleme tetikleyici 1' ve' SET num_rentals = num_rentals - 1' silme tetik –

+0

içinde benim silme tetiği rs içinde tam olarak ne yaptığını ve benim ekleme tetikleyicisi ayarlanır num_rentals = num_rentals + ile yukarı 1. Bir UPDATE tetikleyicisi ile, hem doğru num_rentals sütununa hem de yanlış num_rentals sütunundan çıkarılması için ikili yeteneğe ihtiyacım olmaz mı? – Steve

cevap

-1

Güncelleştirme tetiklendikten sonra gerçekleştirmeniz gerekir. Aşağıdakileri deneyebilirsiniz. tetik daha iyi anlamak için ben şiddetle ekleyerek m.num_rentals tarafından 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 [email protected]_id 
    SET @num_rentals [email protected]_rentals +1; 

     -- perform update here in movies table  

    UPDATE MOVIES SET [email protected]_rentals WHERE movie_id [email protected]_id 

GO 
+0

Size verilen bağlantıya mutlaka dikkat edeceğim, teşekkürler. Declare komutunu tamamen bilmiyorum. Henüz bizim sınıfımızda bununla karşılaşmadık. – Steve

+1

Bu doğru bir yaklaşım değil. Tetikleyicilerin çok satırlı güncellemeleri ele alması gerekir. –

1

Bunu başarabilirsiniz inanıyoruz bu bağlantıyı recommond + 1

Ayrıca da bir güncelleme açıklamada eklemek silinen bir

UPDATE M 
SET num_rentals = m.numrentals - 1 
FROM 
Movies M 
INNER JOIN Deleted D ON 
M.movie_id = D.Movie_ID 

Ancak, bunu tetikleyicilerde kullanmak yerine, uygulamanın bunu kaldırmak için kullanabileceği bir görünüm oluşturmayı tercih ediyorum. Her güncelleme ile gerçekleştirilmesi gereken ekstra veri işleme çıkarmadan Böylece takıp Bir DML beyanı (birden çok satır etkileyebileceğini dikkate almak gerekir

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 
+0

Teşekkürler Christer. Bunu bir tetikleyici aracılığıyla yapmak zorundayım çünkü bu tetikleyiciler üzerinde bir atama. – Steve

7

silmek bu durumda INSERTED ve DELETED tablolar da olacak içinde birden çok satır var.

Ayrıca farklı bir id güncelleniyorsa bir film için kiralama sayısını azaltma olmalıdır dikkate (yanı sıra yeni filmi için sayısını artırarak) gerekmektedir.

Aşağıdaki konsolide sayımları eklerden ayırır ve net değişiklikleri ilgili filmlerde siler ve uygular.

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; 
İlgili konular