![](/img/trans.png)
[英]Create after insert trigger that updates record in parent table after inserting record into child table
[英]How to create delete trigger in SQL on deletion of one record from child table updates the records count in parent table?
我創建了兩個表。第一個是magzine
CREATE TABLE [dbo].[Magzine](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](350) NULL,
[MagzineType] [int] NOT NULL,
[TotalPages] [int] NOT NULL,
[DateCreated] [datetime] NOT NULL,
[Active] [bit] NOT NULL, CONSTRAINT [PK_tblMagzine] PRIMARY KEY CLUSTERED (
[ID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] GO
該列的名稱為TotalPages,用於保存雜志中的總頁數
這是MagzinePage表。
CREATE TABLE [dbo].[MagzinePage](
[ID] [int] IDENTITY(1,1) NOT NULL,
[MagzineID] [int] NOT NULL,
[Title] [nvarchar](255) NULL,
[SubTitle] [nvarchar](255) NULL,
[Photo] [nvarchar](255) NULL,
[Description] [nvarchar](2000) NULL,
[DateCreated] [datetime] NOT NULL,
[CreatedBy] [nvarchar](25) NOT NULL,
[Active] [bit] NOT NULL,
[IsMapped] [bit] NULL, CONSTRAINT [PK_tblPage] PRIMARY KEY CLUSTERED (
[ID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] GO
我已經在magzinePage表中插入數據時創建了一個觸發器,該觸發器可以根據ID對表中插入的記錄總數進行處理,這是觸發器
Alter TRIGGER trgAfterInsert ON [dbo].[MagzinePage]
FOR INSERT
AS
Declare @MagzineID int;
Declare @TotalPages int;
Set @MagzineID= (Select Top 1 MagzineID From MagzinePage Order By ID Desc)
Set @TotalPages = (Select Count(MagzineID) from MagzinePage Where MagzineID=@MagzineID Group By MagzinePage.MagzineID)
Update Magzine Set TotalPages=@TotalPages Where ID= @MagzineID
PRINT 'AFTER INSERT trigger fired.'
GO
現在,我想要創建一個觸發器,該觸發器可以在刪除magzinePage表中的記錄時幫助減少Magzine表中的頁面總數。
請幫我找出一個出路。 謝謝。
您可以創建一個索引視圖,該視圖將始終為您保持最新狀態:
create view dbo.vwMagzinePageCount
with schemabinding
as
select [MagzineID], count_big(*) as TotalPages
from dbo.[MagzinePage]
group by [MagzineID];
go
create unique clustered index cdxMagzinePageCount
on dbo.vwMagzinePageCount (MagzineID);
go
我保留了“雜志”的拼寫。 從許多角度(正確性,性能等)來看,這比觸發器要好得多。 引擎將在任何操作中保持此計數為最新。 從雜志表中刪除TotalPages列。
如果確實由於某種原因需要存儲計數,是否考慮過讓SQL Server為您完成工作? 如果從第一個表中刪除TotalPages
,然后定義此視圖:
CREATE VIEW dbo.MagzineWithPages
WITH SCHEMABINDING
AS
select m.ID,Name,MagzineType,COUNT_BIG(*) as TotalPages,m.DateCreated,m.Active
from
dbo.Magzine m
inner join
dbo.MagzinePage mp
on
m.ID = mp.MagzineID
group by
m.ID,Name,MagzineType,m.DateCreated,m.Active
GO
CREATE UNIQUE CLUSTERED INDEX IX_MagzineWithPages on MagzineWithPages (ID)
然后,在添加和刪除頁面行時, COUNT()
將自動更新。 這還具有您可能希望更新此定義的好處,例如忽略Active
為0的頁面。
為什么你的觸發壞了-像這樣運行的INSERT:
INSERT INTO [dbo].[MagzinePage]([MagzineID],[DateCreated],[CreatedBy],[Active]) VALUES
(1,CURRENT_TIMESTAMP,'Me',1),
(2,CURRENT_TIMESTAMP,'Me also',1)
現在,該表中的TOP 1 MagzineID
將為1
或2
。 您將為其中一個運行更新,而錯過另一個。
如果您確實想將其保留在原始表中(強烈建議,如果您堅持的話,建議您這樣做):
CREATE TRIGGER T_MagzinePage on dbo.MagzinePage
AFTER INSERT,UPDATE,DELETE
AS
SET NOCOUNT ON
;with Deltas as (
select MagzineID,COUNT(*) as Cnt,0 as Del from inserted group by MagzineID
union all
select MagzineID,COUNT(*),1 from deleted group by MagzineID
), Merged as (
select MagzineID,SUM(CASE WHEN Del=0 then Cnt ELSE -Cnt END) as Net
)
update m set TotalPages = TotalPages + Net
from Magzine m
inner join
Merged mm
on
m.MagzineID = mm.MagzineID
應該將其作為單個觸發器(廢除現有觸發器)來完成,並正確處理插入中的多行以及更新更改了MagzineID
以及其他許多問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.