2012-06-28 3 views
0

가 나는 좁은 방은 MagzinePage 표입니다 여기에 magzine자식 테이블에서 한 레코드 삭제시 SQL에서 삭제 트리거를 만드는 방법 부모 테이블의 레코드 개수를 업데이트 하시겠습니까?

에 전체 페이지의 수에 대한 보유 및 열 이름 TotalPages을 가지고 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 

의 두 개의 테이블을 만들었습니다.

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 

I는 여기 ID 대해 표에 삽입 총 레코드 수 돌볼 수 magzinePage 테이블 데이터의 삽입에 트리거를 만들었다는

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 [email protected] Group By MagzinePage.MagzineID) 

     Update Magzine Set [email protected] Where ID= @MagzineID 

     PRINT 'AFTER INSERT trigger fired.' 
    GO 

지금 트리거 인 MagzinePage 테이블의 레코드가 삭제 될 때마다 Magzine 테이블의 총 페이지 수를 줄이는 데 도움이되는 트리거를 만들고 싶습니다.

친절하게도 그 방법을 생각해보십시오. 감사합니다. . 나는 '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 

:

+0

현재 삽입 트리거가 끊어졌습니다. 하나의 '삽입'으로 여러 잡지의 행을 만들 수 있지만 트리거는 하나만 업데이트합니다. 또한 왜 카운트를 저장할 필요가 있다고 생각합니까? 데이터 검색 중에 (예 :'SELECT') 카운트를 수행하면 항상 정확합니다. –

+0

@Damien_The_Unbelieve 나는이 방아쇠가 잘 작동한다고 생각하는데, 나는 magzine에 관한 모든 세부 사항을 표시하는 격자를 보여야하기 때문에 카운트가 필요합니다. 오래 걸리는 것보다 매번 데이터를 가져 오는 것이 좋습니다. 무엇을 제안합니까? –

+0

방아쇠가 끊어진 이유를 보여주는 답변을 끝까지 추가했습니다. –

답변

2

당신은 당신을 위해 최신 모든 시간을 카운트를 유지 인덱싱 된 뷰를 만들 수 있습니다. 이것은 많은 관점 (정확성, 성능 등)에서 트리거보다 훨씬 낫습니다. 엔진은 에이 카운트를 최신 상태로 유지합니다. 이는 작동입니다. Magzine 테이블에서 TotalPages 열을 제거하십시오.

+0

마침내 나는 Linq 쿼리를 사용하여 솔루션을 얻었습니다. 나는 그것을 사랑합니다 ... 피드백을 주신 모든 분들께 감사드립니다. 여기에 내 검색어 인 '공개 getTotalPages INT (INT magId) (DC = SeekDataContextDataContext 새로운 SeekDataContextDataContext()) { 창 dc.MagzinePages.Where (p => p.MagzineID == magId)를 사용 { . 선택 (p => p.ID) .Count(); } } –

2

에 숫자를 저장하려면이 필요합니다. 이유가 무엇이든간에 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()가 자동으로 추가 및 제거 페이지 행으로 업데이트됩니다. 또한이 정의를 업데이트 할 때 도움이 될 수 있습니다.

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이 될 것입니다 :이 같은 INSERT를 실행 - 트리거 깨진Active은 0


입니다 페이지를 무시합니다. 그 중 하나에 대한 업데이트를 실행하고 다른 업데이트를 놓칩니다.


당신이 정말로 (당신의 고집이있는 경우는 내가 강하게 반대 좋을 걸) 원래 테이블에 보관하려면 다음

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이고 다른 많은 문제가 변경되었습니다.

+0

이 테이블 페이지를 사용하여 gridview의 총 개수를 바인딩하기 때문에 전체 페이지 수를 제거 할 수 없습니다. 지금 당장은 내가 프로젝트의 한가운데서 구조를 바꿀 수 없기 때문에 여기있는 트릭을 할 수있는 방아쇠가 필요합니다. 그렇지 않으면 지저분해질 수 있습니다. 이해해 주시기 바랍니다. –

관련 문제