2011-09-05 2 views
2

이 트리거가 있습니다 :트랜잭션이 트리거로 종료되었습니다. 일괄 처리가 중단되었습니다. 유도 된 속성

CREATE trigger [dbo].[DeriveTheAge] on [dbo].[Student] 
after insert,update 
as 
begin 
    declare @sid as int; 
    declare @sdate as date; 
    select @sid= [Student ID] from inserted; 
    select @sdate=[Date of Birth] from inserted; 
    commit TRANSACTION 
    if(@sdate is not null) 
    begin 
     update Student set Age=DATEDIFF(YEAR,@sdate,GETDATE()) where [Student ID][email protected]; 
    end 
    print 'Successfully Done' 
end 

제안에서 트리거는 자동으로 파생 된 특성 "나이"생년월일에서 계산합니다. 하지만 삽입 할 때이 오류가 발생합니다.

(1 row(s) affected) 
Successfully Done 
Msg 3609, Level 16, State 1, Line 1 
The transaction ended in the trigger. The batch has been aborted. 

처음에는 행이 업데이트 된 오류를 가져 오므로이 오류가 발생하지 않았습니다. 하지만 이제 FORNT END 레코드를 삽입 할 때 레코드가 업데이트되지 않습니다. 대신이 예외가 throw됩니다. enter image description here

누구든지 나를 도울 수 있습니까?

btw, SQL Server 2008 R2 및 Visual Studio 2010입니다.

수정 : 레코드가 계속 업데이트 중입니다. 그러나 예외는 빌란입니다.

업데이트

CREATE TRIGGER [dbo].[DeriveTheAge] 
ON [dbo].[Student] 
FOR INSERT, UPDATE 
AS 
BEGIN 
    UPDATE s 
     SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP) 
     FROM dbo.Student AS s 
     INNER JOIN inserted AS i 
     ON s.[Student ID] = i.[Student ID] 
     WHERE i.[Date of Birth] IS NOT NULL; 
     commit transaction 
END 
GO 

답변

7

왜 트리거에 투입된다? 멀티 행 삽입 또는 업데이트를 처리하지 않는 이유는 무엇입니까? 변수를 선언하고 삽입 된 변수를 할당 할 수는 없습니다. 2 또는 15 또는 6000 행을 업데이트 할 때 할당되는 값은 무엇이라고 생각하십니까?

CREATE TRIGGER [dbo].[DeriveTheAge] 
ON [dbo].[Student] 
FOR INSERT, UPDATE 
AS 
BEGIN 
    UPDATE s 
     SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP) 
     FROM dbo.Student AS s 
     INNER JOIN inserted AS i 
     ON s.[Student ID] = i.[Student ID] 
     WHERE i.[Date of Birth] IS NOT NULL; 
END 
GO 

그렇다면 왜 지구상에 누군가의 나이를 계산할 방아쇠가 필요한가요? 현재 쿼리 시간에 생년월일부터이 값을 구할 수 있으며 테이블에 저장된이 오래된 값과는 달리 정확할 것임을 알 수 있습니다. 행이 1 년 넘게 업데이트되지 않으면 표에 넣은 연령이 오래되었습니다. 언제 돌아가서 테이블의 모든 행에 대해 연령을 업데이트합니까? 하루에 한 번? 더 적은 것 및 당신의 나이 란은 완전하게 신뢰할 수없고 무의미하다.

또한 DATEDIFF(YEAR은 처음부터 나이를 계산할 수있는 신뢰할만한 방법이 아닙니다. 그것이하는 모든 것은 교차 된 해 경계의 수를 세는 것입니다. 그 사람의 실제 생일이 1 월 1 일 또는 12 월 31 일인지 그 중간에 있는지는 전혀 알 수 없습니다.

마지막으로 트리거에서 인쇄하지 않습니다. 당신이 디버깅을하지 않을 때 누가 그 print 서술문을 사용할 것인가?

+0

대단히 감사합니다 ... 사실 내 프런트 엔드는 한 번에 하나의 레코드 만 삽입하므로 코드가됩니다. 네, 이제 저는 Age 칼럼에 대한 여러분의 제안에 동의합니다. 정말 나쁜 생각입니다. 또한 나는 print 서술문이 필요 없다는 것을 알게되었다. 실제로 그것은 목적을 확인하기 위해 작성된 후 제거되지 않은 상태로 남았습니다. 마지막으로, 학생의 나이를 얻는 좋은 방법을 제안 할 수 있습니까? – Kameron

+0

아마도 실제로 나이가 필요할 때만 호출되는 함수입니다. http://stackoverflow.com/questions/57599/how-to-calculate-age-in-t-sql-with-years-months-and-days –

+0

나는 당신에게 한 가지 이상의 투표를 할 수 있기를 바란다. ! 다시 감사합니다. – Kameron

관련 문제