2011-08-08 94 views
1

我有相关的表像下面的示例脚本:如何更新子表插入/更新/删除的父表列值?

-- Creating table 'Product' 
CREATE TABLE [dbo].[Product] (
    [Id] int IDENTITY(1,1) NOT NULL, 
    [Text] nvarchar(max) NOT NULL, 
    [AvgRating] decimal(18,2) NOT NULL 
); 
GO 

-- Creating table 'Review' 
CREATE TABLE [dbo].[Review] (
    [Id] int IDENTITY(1,1) NOT NULL, 
    [Text] nvarchar(max) NOT NULL, 
    [Rating] decimal(18,2) NOT NULL, 
    [Product_Id] int NOT NULL 
); 
GO 

-- Creating primary key on [Id] in table 'Product' 
ALTER TABLE [dbo].[Product] 
ADD CONSTRAINT [PK_Product] 
    PRIMARY KEY CLUSTERED ([Id] ASC); 
GO 

-- Creating primary key on [Id] in table 'Review' 
ALTER TABLE [dbo].[Review] 
ADD CONSTRAINT [PK_Review] 
    PRIMARY KEY CLUSTERED ([Id] ASC); 
GO 

-- Creating foreign key on [Product_Id] in table 'Review' 
ALTER TABLE [dbo].[Review] 
ADD CONSTRAINT [FK_ProductReview] 
    FOREIGN KEY ([Product_Id]) 
    REFERENCES [dbo].[Product] 
     ([Id]) 
    ON DELETE NO ACTION ON UPDATE NO ACTION; 

-- Creating non-clustered index for FOREIGN KEY 'FK_ProductReview' 
CREATE INDEX [IX_FK_ProductReview] 
ON [dbo].[Review] 
    ([Product_Id]); 
GO 

我想计算AvgRating对产品行时用户插入/更新/删除审查。我想到的最明显和最残酷的方法是从数据库中提取数据并计算客户端的平均值,然后手动更新产品行。是否可以在数据库服务器上自动执行而不必提取数据?如果是这样,怎么样?数据库托管在MS SQL Server 2008上。

回答

2

您可以在Review表上创建一个触发器。审查更新后,它可以重新计算平均审核。

CREATE TRIGGER TRG_REVIEW 
ON Review 
AFTER INSERT, UPDATE, DELETE 
AS 

;WITH ratings 
AS 
(
    SELECT product_id, AVG(Rating) AS rating 
    FROM Review R 
    WHERE EXISTS (SELECT * FROM INSERTED WHERE product_id = R.product_id AND UPDATE(rating)) 
     OR EXISTS (SELECT * FROM DELETED WHERE product_id = R.product_id) 
    GROUP BY product_id 
) 
UPDATE P set AvgRating = COALESCE(R.rating,0) 
FROM Product P 
INNER JOIN ratings R 
ON P.id = R.Product_id 
+0

非常感谢你,作品像一个魅力。太糟糕了,我不能upvote你的答案呢。 – kondzik

+0

我的快乐,乐于帮助!请注意,我修复了该触发器中的一个错误;删除的表格需要在CTE以及INSERTED中引用。 –

+0

我会给你写额外的积分来编写基于集合的触发器 – HLGEM