我想使用ms sql 2005向我的客户发送电子邮件提醒。我想发送每天应该在午夜左右运行的提醒(当流量很低时)。
所以我认为最好的方法是通过ms sql 2005,我一直在研究sql代理和数据库邮件,但我不确定如何制作一个动态获取每个客户信息的脚本(每个客户都会有发送给他们的另一封电子邮件)。
所以我需要查询一个表来获取每个人的电子邮件地址,我需要一个查询来获取我计划发送的客户信息。
一旦我掌握了这些信息,我就需要格式化电子邮件并发送给他们(如果我有50个客户 - 将发送50个不同的自定义电子邮件)。
To:永远不同的人,From:static可能不会改变,Title-可能会永远不同,Body - 总是不同。
我的身体总是要求它是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 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
好的,在将来的版本中需要注意的几件事我想支持发送电子邮件和短信提醒,因此它们只是在不同类型的同一个表中。 “两者”意味着“电子邮件和短信”警报将被发送出去。
当然现在只需坚持使用电子邮件提醒,但我想向您展示整个故事,但我假设这些将是2个不同的操作,因此可能需要where子句。
接下来的时间日期。我想在午夜左右发出通知,所以午夜到午夜应该是24小时。
因此,如果我们从12月24日12点到12月25日12点,应该发送此范围内的所有通知,然后第二天将是12月25日到12月26日,依此类推。
我也猜测将表A和B连接在一起需要加入。然后我需要抓取数据并将其放入某些变量或其他内容。
那我该怎么写这个sp? KM说我需要循环一些东西或类似的东西。我猜我必须写一些sql类型forloop呢?
答案 0 :(得分:0)
创建在您选择的时间每天运行的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