2010-07-06 87 views
0

我想用ms sql 2005向我的客户发送电子邮件提醒。我想每天发送一些应该在午夜左右运行的提醒(流量很低时)。Sql Agent和数据库邮件是我需要的电子邮件提醒吗?

所以我认为最好的办法是通过MS SQL 2005,我一直在研究SQL代理和数据库邮件,但我不确定如何创建一个脚本来动态获取每个客户的信息(每个客户都会有不同的电子邮件发送给他们)。

所以我需要查询一个表来获取每个人的电子邮件地址,我需要一个查询来获取我计划发送的客户信息。

一旦我有了这些信息,我就需要格式化电子邮件并发送它们(所以如果我有50个客户 - 将发送50个不同的自定义电子邮件)。

致:永远不同的人,来自:静态可能不会改变,标题 - 可能会永远不同,身体 - 永远不同。

我的身体总是会要求它为html,因为我将使用html标签。

那么有人可以给我一个淡化的例子来开始吗?我对数据库没那么好,也没有使用ms sql 2005。

我想我需要SQL代理,因为它可以在设定的时间,当然数据库邮件发送它一切。

但之后它是一个大的空白。我看到这个帖子

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

但她使用触发器所以我不知道有没有结合使用这一点。

编辑

下面是一些表我试图让他们简单,所以我可以理解是怎么回事,可能会是不同的,那么我的最终结果。

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  [email protected].com 
2  [email protected] 
3  [email protected] 


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 

确定这样几件事情要在将来的版本注意我想支持发送了电子邮件和短信提醒,这样他们就可以在同一个表只是用不同的类型。 “Both”意思是“电子邮件和短信”警报将发送出去。

当然,现在只要坚持电子邮件警报,但我想告诉你整个故事,但我假设这些将是2个不同的操作,因此可能需要where子句。

接下来的时间日期。我想在午夜发送通知,所以午夜到午夜应该是24小时。

因此,如果我们从12月24日的12点到12月25日的12点这个范围内的所有通知都应该发出,那么第二天将会在12月25日到12月26日等等。

我也猜测一个连接将需要加入表A和B在一起。然后,我需要获取数据并将其放入一些变量或其他内容中。

那么我怎么写这个sp? KM说我需要循环一些东西或类似的东西。我猜我必须编写一些sql类型forloop呢?

+0

我已更新我的回答 – 2010-07-07 18:04:19

回答

0

创建一个SQL Server代理作业,该作业每天在您选择的时间运行。让那份工作运行一个存储过程。在该存储过程中,您需要循环发送电子邮件所需的任何内容。每个不同的电子邮件重复一次,呼叫EXEC msdb.dbo.sp_send_dbmail ...,...,..发送实际的电子邮件。除此之外,你需要提出具体的问题。您需要将收件人电子邮件地址列表构建到本地变量中,并构建邮件正文,但是在问题中没有任何详细信息,我该如何解释要执行的操作?

编辑后OP的更多的细节编辑:

设置表,我用@TableVariables,因为我不想我的测试系统上创建表,您需要创建常规表,在适当的PK ,FKS,索引等

SET NOCOUNT ON 
DECLARE @EmailContacts table (EmailID  int 
          ,EmailAddress varchar(20) 
          ) 
INSERT @EmailContacts VALUES (1,'[email protected]') 
INSERT @EmailContacts VALUES (2,'[email protected]') 
INSERT @EmailContacts VALUES (3,'[email protected]') 

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>[email protected] 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 @[email protected]@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   [email protected]_EmailAddress 
            ,@body     [email protected]_MessageBody 
            ,@body_format   ='HTML' 
            ,@subject    [email protected]_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 

OUTPUT:

Sending mail, TO: [email protected], SUBJECT: Reminder1, BODY: <b>test</b> 
Sending mail, TO: [email protected], SUBJECT: Reminder2, BODY: hello 
+0

感谢您提供的这些信息,这些信息已经有所帮助。就细节而言,我可以制作一些非常简单的伪造表格,我们可以从这里开始。就像我说过的,我并不太了解ms sql,所以现在很难得到具体的问题,因为大部分问题都是空白的。 – chobo2 2010-07-06 19:18:31

+0

Thansk我会检查出来,但首先我得到测试电子邮件的东西工作。它不会发送我的电子邮件。 – chobo2 2010-07-07 18:13:37