Sql Agent and Database mail - это то, что мне нужно для напоминаний по электронной почте? - PullRequest
0 голосов
/ 06 июля 2010

Я хочу использовать MS SQL 2005 для отправки напоминаний по электронной почте своим клиентам.Я хочу отправлять ежедневные напоминания, которые должны запускаться около полуночи (когда трафик будет низким).

Так что я думаю, что лучший способ сделать это - через MS SQL 2005, и я искал агент SQL и почту базы данных, ноЯ не уверен, как создать сценарий, который бы динамически получал информацию для каждого клиента (каждому клиенту будет отправлено отдельное электронное письмо).

Поэтому мне нужно запросить одну таблицу, чтобы получить все адреса электронной почты, яМне нужен запрос, чтобы получить информацию о клиентах, которую я планирую отправить.

Как только у меня будет эта информация, мне нужно будет отформатировать письмо и отправить его (так что если у меня будет 50 клиентов - 50 различных настроенных писем будутбыть отправленным).

Кому: Всегда другой человек, От: статика, вероятно, не изменится, Название - вероятно, всегда будет другим, Тело - Всегда другое.это будет html, так как я буду использовать html тэги.

Так может ли кто-нибудь дать мне пример с разводкой, чтобы начать?Я не настолько хорош с базами данных и не очень часто использую ms sql 2005.

Я думаю, что мне нужен sql agent, так как он может это делать в установленное время, и, конечно, почта базы данных, чтобы отправить все это.

Но после этого это большой пробел.Я видел этот пост

http://blog.netnerds.net/2008/02/create-a-basic-sql-server-2005-trigger-to-send-e-mail-alerts/

, но она использует триггеры, поэтому я не знаю, нужно ли мне использовать это также в комбинации.

Edit

Вот некоторые таблицы, которые я стараюсь сделать их простыми, чтобы я мог понять, что происходит, и, вероятно, будет отличаться от моего конечного результата.

Table A
id - pk - incrementing int
email - varchar(20)

Table B
TableBId  - pk - incrementing int
id - fk
title - varchar(30)
body - varchar(2000)
SendOutDate - datetime
type - varchar(5)

Примеры данных

Table A

Id       email
------------------
1       test@hotmail.com
2       bob@hotmail.com
3       jim@gmail.com


Table B
TableBId   Id   title          body          sendoutDate           type
---------------------------------------------------------------------------
1          1    Reminder1     <b>test</b>    12/24/2010 12:30 pm    Email
2          1    Reminder2     hello          12/25/2010 12:30 pm    Email
3          1    Reminder3     hi text        12/28/2010 11:30 pm    SMS
4          1    Reminder4     again          12/29/2010 5:00am      Both
5          2    Your Reminder  test          12/24/2010 2:30 am     Email
6          3    jim            bo            12/25/2010 11:59:59 pm   SMS

Итак, пара замечаний в будущей версии. Я хочу поддержать отправку оповещений по электронной почте и SMS, чтобы они были в одной таблице только с другим типом.«Оба», означающие «Электронная почта и SMS», будут отправлены.

Конечно, сейчас давайте просто придерживаться уведомлений по электронной почте, но я хотел показать вам всю историю, но я предполагаю, что это будут 2 разные операциипоэтому, возможно, понадобится предложение where.

Следующая дата времени.Я хочу разослать уведомление около полуночи, поэтому с полуночи до полуночи должно быть 24 часа.

Так что если мы с 24 декабря по 12:00 до 25 декабря по 12 вечера все уведомления в этом диапазоне должны быть отправлены, то следующий день будет декабрьС 25 по 26 декабря и т. Д.

Я также предполагаю, что объединение будет необходимо для объединения таблиц А и В.Тогда мне нужно было бы собрать данные и поместить их в некоторые переменные или что-то в этом роде.

Так как я мог написать этот sp?КМ говорил, что мне нужно перебрать кое-что или что-то в этом роде.Я предполагаю, что мне нужно написать какой-то тип sql forloop тогда?

1 Ответ

0 голосов
/ 06 июля 2010

Создайте задание агента SQL Server, которое будет выполняться ежедневно в выбранное вами время. Пусть это задание запустит хранимую процедуру. В этой хранимой процедуре вам нужно перебрать все, что вам нужно для отправки электронного письма. Одна итерация для каждого отдельного электронного письма, вызывая EXEC msdb.dbo.sp_send_dbmail ...,...,.. для отправки реального электронного письма. Кроме того, вам нужно задать конкретные вопросы. Вам нужно будет составить список адресов электронной почты получателей в локальной переменной, а также создать тело сообщения, но без каких-либо подробностей в вопросе, как я могу объяснить, что делать?

РЕДАКТИРОВАТЬ после редактирования ОП с более подробной информацией:

Настроив таблицы, я использовал @TableVariables, потому что я не хочу создавать таблицы в моей тестовой системе, вам нужно создавать обычные таблицы с соответствующими PK, FK, индексами и т. Д.

SET NOCOUNT ON
DECLARE @EmailContacts table (EmailID      int
                             ,EmailAddress varchar(20)
                             )
INSERT @EmailContacts VALUES (1,'test@hotmail.com')
INSERT @EmailContacts VALUES (2,'bob@hotmail.com')
INSERT @EmailContacts VALUES (3,'jim@gmail.com')

DECLARE @EmailMessages table (MessageId     int
                             ,MessageType   char(1)  --FK to EmailMessageType.MessageType
                             ,EmailID       int          --FK to EmailContacts.EmailID
                             ,SendOutDate   datetime
                             ,MessageTitle  varchar(30)
                             ,MessageBody   varchar(2000)
                             )
INSERT @EmailMessages VALUES(1,'E', 1,'12/24/2010 12:30 pm'   , 'Reminder1'     ,'<b>test</b>')
INSERT @EmailMessages VALUES(2,'E', 1,'12/24/2010 12:30 pm'   , 'Reminder2'     ,'hello'      ) --<<changed date so there would be multiple to loop over
INSERT @EmailMessages VALUES(3,'S', 1,'12/28/2010 11:30 pm'   , 'Reminder3'     ,'hi text'    )
INSERT @EmailMessages VALUES(4,'B', 1,'12/29/2010 5:00 am'    , 'Reminder4'     ,'again'      )
INSERT @EmailMessages VALUES(5,'E', 2,'12/24/2010 2:30 am'    , 'Your Reminder' ,'test'       )
INSERT @EmailMessages VALUES(6,'S', 3,'12/25/2010 11:59:59 pm', 'jim'           ,'bo'         )

DECLARE @EmailMessageTypes table (MessageType           char(1)
                                 ,MessageTpeDescription varchar(30)
                                 )
INSERT @EmailMessageTypes VALUES ('E','Email')
INSERT @EmailMessageTypes VALUES ('S','SMS')
INSERT @EmailMessageTypes VALUES ('B','Both')
SET NOCOUNT OFF

это то, что входит в хранимую процедуру

--inside the stored procedure
BEGIN TRY

    DECLARE @RunDate        datetime
           ,@ReturnValueX   int
           ,@ErrorMsg       varchar(5000)
           ,@Rows           int

    SET @RunDate='12/24/2010 12:30 pm'  --GETDATE() --<<use GETDATE() I used '12/24... so it would find the test data

    --area to process current row from loop
    DECLARE @Process_MessageId              int
           ,@Process_MessageType            char(1)
           ,@Process_MessageTpeDescription  varchar(30)
           ,@Process_EmailID                int     
           ,@Process_EmailAddress           varchar(20)     
           ,@Process_SendOutDate            datetime
           ,@Process_MessageTitle           varchar(30)
           ,@Process_MessageBody            varchar(2000)

    SET @Process_MessageId=0

    WHILE ISNULL(@Process_MessageId,-1)>=0
    BEGIN
        --get the next row to process
        SELECT
            @Process_MessageId                  =m.MessageId
                ,@Process_MessageType           =m.MessageType 
                ,@Process_MessageTpeDescription =t.MessageTpeDescription
                ,@Process_EmailID               =m.EmailID    
                ,@Process_EmailAddress          =c.EmailAddress 
                ,@Process_SendOutDate           =m.SendOutDate 
                ,@Process_MessageTitle          =m.MessageTitle
                ,@Process_MessageBody           =m.MessageBody 
            FROM @EmailMessages      m
                INNER JOIN (SELECT
                                MIN(mm.MessageId) AS MinMessageId
                                FROM @EmailMessages  mm
                                WHERE mm.MessageId>@Process_MessageId AND mm.SendOutDate>=@RunDate AND mm.SendOutDate<=DATEADD(hour,1,@RunDate)
                           ) dt ON m.MessageId=MinMessageId
                LEFT OUTER JOIN @EmailMessageTypes t ON m.MessageType=t.MessageType
                LEFT OUTER JOIN @EmailContacts     c ON m.EmailID=c.EmailID
        SELECT @Rows=@@ROWCOUNT

        IF @Rows=0
        BEGIN
            BREAK --no more rows found
        END

        --process the row
        --comment out the PRINT when it is in production, it is nice have when running it from SQL Server Management Studio, but not necessary when run from a job
        PRINT 'Sending mail, TO: '+ISNULL(@Process_EmailAddress,'null')+', SUBJECT: '+ISNULL(@Process_MessageTitle,'null')+', BODY: '+ISNULL(@Process_MessageBody,'null')
        EXECUTE @ReturnValueX = msdb.dbo.sp_send_dbmail
                                    @recipients            =@Process_EmailAddress
                                   ,@body                  =@Process_MessageBody
                                   ,@body_format           ='HTML'
                                   ,@subject               =@Process_MessageTitle
                                   ,@profile_name          ='YourEmailProfile'

        IF @ReturnValueX!=0
        BEGIN
            SET @ErrorMsg='Error '+ISNULL(CONVERT(varchar(30),@ReturnValueX),'unknown')+', calling msdb.dbo.sp_send_dbmail '
                                 +'   @recipients='            +ISNULL(@Process_EmailAddress  ,'null')
                                 +'  ,@body='                  +ISNULL(@Process_MessageBody   ,'null')
                                 +'  ,@body_format='           +ISNULL('HTML'                 ,'null')
                                 +'  ,@subject='               +ISNULL(@Process_MessageTitle  ,'null')
                                 +'  ,@profile_name='          +ISNULL('YourEmailProfile'     ,'null')
            RAISERROR(@ErrorMsg,16,1) --send control to the BEGIN CATCH block
        END --IF ERROR

    END --WHILE

END TRY
BEGIN CATCH

    --use your error logging method of choice here
    --INSERT INTO YourErrorLogTable (...,...,...) VALUES (...,...,...,'fatal error in '+ISNULL(OBJECT_NAME(@@PROCID), 'unknown')
    --             +' error was :'
    --             +CASE WHEN ERROR_NUMBER()     IS NOT NULL THEN 'Msg '         +CONVERT(varchar(30),   ERROR_NUMBER()     ) ELSE '' END
    --             +CASE WHEN ERROR_SEVERITY()   IS NOT NULL THEN ', Level '     +CONVERT(varchar(30),   ERROR_SEVERITY()   ) ELSE '' END
    --             +CASE WHEN ERROR_STATE()      IS NOT NULL THEN ', State '     +CONVERT(varchar(30),   ERROR_STATE()      ) ELSE '' END
    --             +CASE WHEN ERROR_PROCEDURE()  IS NOT NULL THEN ', Procedure ' +                       ERROR_PROCEDURE()    ELSE '' END
    --             +CASE WHEN ERROR_LINE()       IS NOT NULL THEN ', Line '      +CONVERT(varchar(30),   ERROR_LINE()       ) ELSE '' END
    --             +CASE WHEN ERROR_MESSAGE()    IS NOT NULL THEN ', '           +                       ERROR_MESSAGE()      ELSE '' END

    --will echo back the complete original error message
    DECLARE @ErrorMessage nvarchar(4000), @ErrorNumber int, @ErrorSeverity int, @ErrorState int, @ErrorLine int
    SELECT @ErrorMessage = N'Error %d, Line %d, Message: '+ERROR_MESSAGE(),@ErrorNumber = ERROR_NUMBER(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE(),@ErrorLine = ERROR_LINE()
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber,@ErrorLine)
    --RETURN 9999

END CATCH

ВЫВОД:

Sending mail, TO: test@hotmail.com, SUBJECT: Reminder1, BODY: <b>test</b>
Sending mail, TO: test@hotmail.com, SUBJECT: Reminder2, BODY: hello
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...