2010-07-29 5 views
0
USE [ddb] 
GO 
SET ANSI_NULLS OFF 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE TRIGGER [dbo].[requeststrigger] 
ON [dbo].[requests] 
AFTER INSERT,UPDATE 
AS 
BEGIN 
DECLARE @email VARCHAR(400); 
DECLARE @firstname VARCHAR(400); 
DECLARE @requestno VARCHAR(400); 
DECLARE @lastname VARCHAR(400); 
DECLARE @statusid INT; 
DECLARE thecursor CURSOR FOR SELECT inserted.requestno,contacts.firstname,contacts.lastname,contacts.email FROM request_contacts,contacts,inserted WHERE request_contacts.requestid=inserted.requestid AND contacts.contactid=request_contacts.contactid AND request_contacts.notification=1 AND contacts.notification=1; 

SET @statusid = (SELECT statusid FROM inserted); 

IF @statusid = 4 AND @statusid <> (SELECT statusid FROM deleted) 
BEGIN 

SET NOCOUNT ON 
SET ARITHABORT ON 
OPEN thecursor; 

    FETCH NEXT FROM thecursor 
    INTO @requestno,@firstname,@lastname,@email 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     EXEC MAIL_SEND @email,@firstname,@requestno,@lastname; 

    FETCH NEXT FROM thecursor 
    INTO @requestno,@firstname,@lastname,@email 

    END 
CLOSE thecursor; 

DEALLOCATE thecursor 

SET NOCOUNT OFF 
END 

END 

이렇게하면 전체 UPDATE/INSERT가 작동하지 않게됩니다. 커서 선언을 제거하면 작동합니다. 커서는 "연락처"라는 동일한 데이터베이스에있는 테이블의 필드를 선택하는 것입니다. 뭐가 잘못 되었 니?트리거 내부의 커서가 작동하지 않습니다.

+0

정확히 무엇을하려합니까? – gbn

+0

TABLE1 트리거가 발생하면 (행이 삽입/업데이트 될 때마다) TABLE2 다른 테이블로 이동하여 TABLE1의 해당 레코드와 연관된 레코드를 외래 키를 통해 가져 와서 그 결과를 반복합니다 그들과 함께 뭔가를하기 위해 프로 시저를 호출하는 것. – johnshaddad

+0

도움이 될만한 아이디어가 있으십니까? – johnshaddad

답변

2

디자인 수정을 고려할 준비가 되셨습니까? 여기에 시도한 것과 몇 가지 문제가있는 것으로 보입니다.

트리거가 원본 테이블에 대한 변경 내용과 인라인으로 실행되므로이 ​​종류의 행 단위 작업을 수행하는 데 가장 적합한 장소 일 필요는 없으며 시스템 성능에 부정적인 영향을 미칩니다.

또한 기존 코드는 배치의 단일 행에 대해서만 statusid을 평가하지만 논리적으로 단일 배치 업데이트에서 둘 이상의 값으로 설정할 수 있습니다. 각 작업은 한 번만 수행되도록

보다 강력한 방법은 플래그를 설정, 예약 된 작업 행을 선택하고 MAIL_SEND을 실행할 수있는 큐잉 테이블에 MAIL_SEND 작업을 생성해야 행을 삽입 할 수 있습니다 .

이렇게하면 인서트에 대한 트리거가 간단 해집니다. 커서는 필요하지 않습니다 (여전히 잡다한 작업에서 어떤 종류의 루프가 필요함).

관련 문제