0

次のストアドプロシージャは、エージェントによって5分ごとに実行されます。このプロシージャControl_EmailQueueを使用してテーブルをスキャンし、送信する新しい電子メールがあるかどうかを確認します。

間違った電子メール情報がテーブルに入力されたときにprocがどのように動作するかをテストしたかったのControl_EmailQueueです。2つのテストとその結果を以下に詳しく説明します。

TEST13つのフィールドすべてにエントリが
あるレコードを追加します。これは正常に機能します。つまり、エラーがトラップされ、内部のコードが実行されるため、「Control_EmailQueueNULLEmailTO/EmailCC and EmailBCCCATCH'ERROR OCCURED DURING EMAIL CREATION'

TEST2
にレコードを追加しControl_EmailQueueます。フィールドEmailTOにこの文字列を入力します。'me@me.co.uk; xxxxxxx@xxxxx'つまり、最初のメールアドレスは有効ですが、2番目のメールアドレスは無効です。プロシージャがエージェントによって実行されると、によって電子メールが受信されますme@me.co.ukが、0.5秒後に別の同じ電子メールがによって受信されme@me.co.ukます。タイトルのCATCH電子メールが受信されないため、このテストではコードは実行され'ERROR OCCURED DURING EMAIL CREATION'ません。

BEGIN TRY

    DECLARE @Exit TINYINT = 0
    WHILE @Exit = 0
        BEGIN

        BEGIN TRANSACTION

            DECLARE @MailIdFound INT =
            (
            SELECT 
                    CASE 
                            WHEN MIN([EmailId]) IS NULL THEN 0
                            ELSE MIN([EmailId])
                    END
            FROM [xxx].[console].[Control_EmailQueue]
            WHERE
                    [DateInsertKey] IS NOT NULL 
                    AND
                        ( --the following gives option to re-run past mails by updating DateEmailKey to NULL
                        [DateEmailKey] IS NULL
                        OR
                        [DateEmailKey] < [DateInsertKey]
                        )
                    AND 
                    ErrorOccured = 0
                    AND 
                    EmailActive = 1
            )

            IF @MailIdFound = 0 
            BEGIN SET @Exit = 1 END --exit here as  
            ELSE

            BEGIN --send the mail here

                    --DECLARE @EmailId INT
                    DECLARE @DateInsertKey INT
                    DECLARE @DateEmailKey INT
                    DECLARE @CallingReportName NVARCHAR(1000)
                    DECLARE @EmailBCC  NVARCHAR(1000)
                    DECLARE @EmailTO  NVARCHAR(1000)
                    DECLARE @EmailCC NVARCHAR(1000)
                    DECLARE @EmailBody NVARCHAR(MAX)
                    DECLARE @EmailAttachmentPath NVARCHAR(1000)
                    DECLARE @EmailImportance VARCHAR(6)
                    DECLARE @EmailSubject NVARCHAR(1000)

                    ;WITH myMostUrgentMail_cte
                    AS
                            (
                            SELECT 
                                    TOP 1
                                    --[EmailId],
                                    [DateInsertKey],
                                    [DateEmailKey],
                                    [CallingReportName],
                                    [EmailBCC],
                                    [EmailTO],
                                    [EmailCC],
                                    [EmailBody],
                                    [EmailAttachmentPath],
                                    [EmailImportance],
                                    [EmailSubject]
                            FROM [xxx].[console].[Control_EmailQueue]
                            WHERE [EmailId] = @MailIdFound
                            )
                    SELECT 
                            @DateInsertKey          = [DateInsertKey],
                            @DateEmailKey           = [DateEmailKey],
                            @CallingReportName = [CallingReportName],
                            @EmailTO                    = [EmailTO],        
                            @EmailCC                    = [EmailCC],                        
                            @EmailBCC               = [EmailBCC],
                            @EmailBody              = [EmailBody],
                            @EmailAttachmentPath = [EmailAttachmentPath],
                            @EmailImportance        = CASE 
                                                                                WHEN [EmailImportance] = 0 THEN 'Low'
                                                                                WHEN [EmailImportance] = 1 THEN 'Normal'
                                                                                WHEN [EmailImportance] = 2 THEN 'High'
                                                                    END,
                            @EmailSubject           = [EmailSubject]
                    FROM myMostUrgentMail_cte


                    SET @EmailBody = @EmailBody + '<b>Please contact us with any questions</b></p></span></html>'
                    EXEC msdb..sp_send_dbmail
                            @recipients                     = @EmailTO,  
                            @copy_recipients            = @EmailCC,
                            @blind_copy_recipients  = @EmailBCC,
                            @subject                            = @EmailSubject,
                            @file_attachments          = @EmailAttachmentPath,
                            @Importance                 = @EmailImportance,
                            @body_format                    = 'html',
                            @body                               = @EmailBody    

                    UPDATE x
                    SET 
                                x.[DateEmailKey]        = (CONVERT(CHAR(8),GETDATE(),(112))),
                                x.[DateEmailTime]   = (CONVERT([time](7),left(CONVERT([char](12),GETDATE(),(114)),(8)),(0)))
                    FROM [xxx].[console].[Control_EmailQueue] x
                    WHERE x.[EmailId] = @MailIdFound

            END

        COMMIT TRANSACTION

        END

END TRY



BEGIN CATCH

     IF @@trancount>0 
        BEGIN
                ROLLBACK TRANSACTION
        END

    -- handle error here
    DECLARE @ErrorMessage VARCHAR(100) =  '<html><p>Error occured during creation of EmailId: ' + CONVERT(VARCHAR(10),@MailIdFound) + '</p><p>xxx.console.Control_EmailQueue</p></html>'
    EXEC msdb..sp_send_dbmail
            @recipients = 'me@me.co.uk;'
            , @subject = 'ERROR OCCURED DURING EMAIL CREATION'
            , @body_format = 'html'
            , @body = @ErrorMessage

    UPDATE x
    SET x.ErrorOccured = 1
    FROM [xxx].[console].[Control_EmailQueue] x
    WHERE x.[EmailId] = @MailIdFound

END CATCH;
END
4

1 に答える 1

1

この問題は、トランザクションのタイミングに関連しているようです。コミット後に遅延を追加することにより、トランザクションは、次のループが実行される前に完了してコミットすることができます。

おそらく行うべきことの1つは、sp_send_dbmailからmailitem_idを取得することです。おそらくあなたは正しく、失敗していますが、エラーではありませんが、それはトランザクションに影響を与えるべきではありません。私が考えることができる唯一のことは、トランザクションが実際にはまだコミットされていないためにダーティまたはファントム読み取りが発生していることです。したがって、わずかな遅延により、データが実際にコミットされます。

于 2012-11-28T01:58:05.063 に答える