2012-10-02 3 views
0

SQL 브로커를 사용하여 일부 비동기 작업 (내 경우에는 메일 발송)을 수행하고 있습니다. 하지만 내가 가지고있는 문제는 XML 메시지가 트리거에서 대기열로 전달 될 때마다 값이 대기열에 삽입 될 때 실행되는 저장 프로 시저입니다.SQL 브로커 큐가 두 번 채우는 중

CREATE SERVICE MailSendActivator 
AUTHORIZATION dbo 
ON QUEUE dbo.MessageQueue (MailContract) ; // I have removed this the contract to make it a initiator but it did not worked out 

-- Create target Service 
CREATE SERVICE MailSendExec 
AUTHORIZATION dbo 
ON QUEUE dbo.MessageQueue (MailContract); 
: 나는 두 가지 서비스를

CREATE QUEUE dbo.MessageQueue 
WITH STATUS=ON, 
ACTIVATION ( 
PROCEDURE_NAME = MailExecuter , 
MAX_QUEUE_READERS = 1, 
EXECUTE AS OWNER); 

: 나는 대기열이

CREATE CONTRACT MailContract 
AUTHORIZATION dbo 
(MailMessage SENT BY INITIATOR) 

: 나는 계약을 체결 한

CREATE MESSAGE TYPE MailMessage 
AUTHORIZATION dbo 
VALIDATION = WELL_FORMED_XML 

:

나는 메시지 유형이 0 저장 프로 시저의 실행 여부를 제가 테스트 테이블에 값을 삽입하고 저장 프로 시저에서 : 내가 저장 프로 시저를

CREATE TRIGGER MailSendTrigOnMailQueue ON dbo.MailQueue 
FOR INSERT 
As 
SET NOCOUNT ON; 

DECLARE @MessageBody XML 
DECLARE @TableId int 


SET @MessageBody = (SELECT CreatedDateTime,[Subject], MailType FROM inserted 
FOR XML AUTO) 


If (@MessageBody IS NOT NULL) 
BEGIN 

DECLARE @Handle UNIQUEIDENTIFIER; 
BEGIN DIALOG CONVERSATION @Handle 
FROM SERVICE MailSendActivator 
TO SERVICE 'MailSendExec' 
ON CONTRACT MailContract 
WITH ENCRYPTION = OFF; 

SEND ON CONVERSATION @Handle MESSAGE TYPE MailMessage(@MessageBody); 

END 

:

여기 내 트리거입니다.

저장 프로 시저 :

CREATE PROCEDURE dbo.MailExecuter 
AS 
BEGIN 

DECLARE @msgBody XML  
DECLARE @dlgId uniqueidentifier 
Insert into TestTable(Name, Test) values('MEX','test'); 
WHILE (1 = 1) 
    BEGIN 

      WAITFOR (RECEIVE TOP(1) @msgBody = CAST(message_body AS XML),  @dlgId = conversation_handle FROM dbo.MessageQueue), TIMEOUT 500  
      IF (@@ROWCOUNT = 0 OR @msgBody IS NULL) 
       BEGIN 
        BREAK 
       END 
      ELSE 
       BEGIN 


       DECLARE @Subject nvarchar(200), @CreatedDateTime datetime, @MailType nvarchar(50) 


       ---EXEC dbo.SendMails 1,1; 

       END 
      END CONVERSATION @dlgId 

      END 

    END 

그러나 저장 프로 시저를 두 번 실행하고 두 번 내 테스트 테이블을 채우는된다. 문제는 방아쇠에있는 부분이 send conversation 인 것 같습니다.

나는 오랫동안 이것을 쳤다. 제발, 도와 줄 수 있어요.

+0

글쎄, 당신은 방아쇠가 깨졌습니다 * 어쨌든 *, 그것은'삽입 '은 단일 행을 포함한다고 가정하기 때문에. 당신의 문제에 대한 해결책은 아니지만 문제를 해결할 다른 문제 (환영합니다 :-)) –

+0

@Damien -'for xml auto'? – RichardTheKiwi

+0

@Damien_The_Unbeliever 그래서 내가 제안한 것은 삽입 된 테이블에 한 번에 두 개 이상의 레코드가있는 디자인을 생각해 내야한다는 것입니다. rite –

답변

3

투영 목록 message_type_name을 추가해야합니다. 받은 메시지 유형을 확인하고 메시지 유형이 MailMessage 인 경우 만 메일 링 루틴을 호출해야합니다. 상황에 따라 항상 두 번째 메시지가 표시됩니다. 즉, END DIALOG의 메시지입니다. 이 경우 다시 END DIALOG를 호출하여 송신 측 핸들을 닫아야합니다.

WAITFOR ( 
     RECEIVE TOP(1) 
     @msgBody = CAST(message_body AS XML),  
     @dlgId = conversation_handle , 
      @msgType = message_type_name 
     FROM dbo.MessageQueue), TIMEOUT 500  
    IF (@@ROWCOUNT = 0 OR @msgBody IS NULL) 
     BREAK 
    ELSE IF @msgType = N'MailMessage' 
    BEGIN 
     DECLARE @Subject nvarchar(200), @CreatedDateTime datetime, @MailType nvarchar(50) 
     ---EXEC dbo.SendMails 1,1; 
    END 

    END CONVERSATION @dlgId; 

휠을 다시 발명하는 특별한 이유가 있습니까? 이것은 sp_send_dbmail이 이미 작동하는 방식입니다 (외부 활성화 사용 제외).

+0

와우 감사합니다. 많은,이 SendMails 저장 프로 시저뿐만 아니라 다른 여러 저장 프로 시저에서 사용됩니다 :) –