Sending HTML Newsletters in a Batch Using SQL Server

  • Comments posted to this topic are about the item Sending HTML Newsletters in a Batch Using SQL Server

  • that's pretty beautiful, however I am not SQL Server Expert

    if any one tried it, would you please provide something such as a template that non-expert users can use?

    all help is appreciated

  • The article is designed in beautiful manner...

    The script are written in simple manner, so it helped me to understand the whole concept.:-)

    Thanks,

    Pankaj.

  • Nice article. Some questions though. If I want to include Cc and Bcc fields in the emails, how do I do it? How about the email Priority (Low, Normal, High Importance)

    Personally, I find it easier to create a simple C# application. I would create an HTML template and shoot the desired info from the database to template so that it looks like a nice HTML email. Using dynamic sql to build the HTML can be challenging for more complex emails (with formatting).

    Sample:

    CustomerList.htm:

    <tr>

    <td style="width:50px; text-align:center; color:Blue">

    [SNo]

    </td>

    <td style="width:150px; text-align:left; color:Blue">

    [CustomerCode]

    </td>

    <td style="width:300px; text-align:left; color:Blue">

    [CustomerName]

    </td>

    <td style="width:50px; text-align:center; color:Blue">

    [CustomerType]

    </td>

    <td style="width:50px; text-align:center; color:Blue;">

    [CustomerRank]

    </td>

    </tr>

    MainEmail.htm (headers, embedded styles and other formatting are removed)

    <tr>

    <td>

    <table>

    <tr class="DataGridHeaderGray">

    <td style="width:50px; text-align:center">

    S. No.

    </td>

    <td style="width:150px; text-align:center">

    Customer Code

    </td>

    <td style="width:400px; text-align:center">

    Customer Name

    </td>

    <td style="width:50px; text-align:center">

    Type

    </td>

    <td style="width:50px; text-align:center">

    Rank

    </td>

    </tr>

    [CUSTOMERLIST]

    </table>

    </td>

    </tr>

    Then create a StreamReader that will read the contents of the template. Loop through your list of, replace the tags in square brackets (SNo, CustomerCode, etc). Set the recipients (To, Cc and Bcc). Create a MailMessage object and send the email.

    Of course, there are other different ways. Cheers!

  • Many Thanks to you. In order to achieve the results, use the below T-SQL query:

    EXEC msdb.dbo.sp_send_dbmail

    @profile_name = 'Profile Name',

    @recipients=@cs_application_email,

    @copy_recipients ='EMail addresses to be included in cc',

    @blind_copy_recipients='EMail addresses to be included in bcc',

    @sensitivity ='High/Normal/Low'

    @subject ='Subject Of The EMail',

    @body = @query,

    @body_format = 'HTML' ;

  • I've been using the send mail functionality for a while now and have found so many uses for it, it's really cool. I send out morning reports using an HTML template or sending out pretty emails to customers, like this...

    The weekly report style

    DECLARE @TableHTML VARCHAR(MAX)

    SET @tableHTML =

    N'<H1>Weekly Report For Week Beginning '+CONVERT(VARCHAR(20),dbo.ConvertTo5amDate(DATEADD(wk, DATEDIFF(wk,0,@Start), 0)))+'</H1>' +

    N'<style type="text/css">' +

    N'table {' +

    N'font-family: Arial, Helvetica, sans-serif;' +

    N'font-size: small;' +

    N'color: #111111;' +

    N'background-color: #EEEEEE;' +

    N'}' +

    N'</style>' +

    N'<table border="1">' +

    N'<tr><th>Col 1</th>' +

    N'<th>Col 2</th>' +

    N'<th>Col 3</th>' +

    N'<th>Col 4</th></tr>' +

    CAST ( (

    SELECT

    td = [Period],''

    ,td = [Total],''

    ,td = [Processed],''

    ,td = [NotProcessed],''

    FROM #Table

    FOR XML PATH('tr'), TYPE

    ) AS NVARCHAR(MAX) ) +

    N'</table>' ;

    IF @@ERROR<>0

    BEGIN

    exec msdb.dbo.sp_send_dbmail @recipients = 'errors@here.co.uk'

    ,@body = 'An error occurred in the execution of [WeeklyReport]'

    ,@subject = 'ERROR mail from the database'

    ,@reply_to = 'me@here.co.uk'

    END

    ELSE

    BEGIN

    exec msdb.dbo.sp_send_dbmail @recipients = 'thisdistributionlist@here.co.uk'

    ,@body_format = 'HTML'

    ,@body = @TableHTML

    ,@subject = @SubjectLine

    ,@reply_to = 'me@here.co.uk'

    END

    And the pretty email style

    DECLARE @TableHTML VARCHAR(MAX)

    SET @UserEmail = LTRIM(rtrim(@UserEmail))

    SET @TableHTML ='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html>

    <head>

    <title>My document title</title>

    </head>

    <body> HI ' + @UserName + ' thanks for whatever you have done on our website, this is a generic confirmation message. Check out these boobies while you wait for something else to happen

    <img src="http://www.destructoid.com/elephant//ul/1929-468x-boobies.jpg">

    </body>

    </html>'

    IF @@ERROR<>0

    BEGIN

    exec msdb.dbo.sp_send_dbmail @recipients = 'errors@here.co.uk;'

    ,@body = 'An error occurred in the execution of the SendSexualEmail'

    ,@subject = 'ERROR mail from the database'

    ,@reply_to = 'me@here.co.uk'

    END

    ELSE

    BEGIN

    exec msdb.dbo.sp_send_dbmail @recipients = @UserEmail

    ,@from_address = 'noreply@here.co.uk'

    ,@body_format = 'HTML'

    ,@body = @TableHTML

    ,@subject = 'Your Sexual Email'

    ,@reply_to = 'me@here.co.uk'

    END

    There's tonnes more stuff you can do and obviously I don't spend all my day sending people images of boobies.

  • Nice article and it made me look back at some stuff I had done a while back and re-jig it to fit in with this.

    I took a slightly different take on generating the mail batches. Also I was not sure why you needed the @query in there twice rather than generating beforehand.

    My other different approach is to curse through each batch and semi-colon separate all the addresses into one addresses line:

    --declare the tables for use

    DECLARE @tempemails TABLE(emailID INT IDENTITY(1,1), emailAddress NVARCHAR(100))

    DECLARE @emailBatches TABLE(batchID INT IDENTITY(1,1), startID INT, endID INT)

    DECLARE @batchSize INT

    DECLARE @totalMails INT

    DECLARE @startID INT

    DECLARE @endID INT

    DECLARE @emailAddresses NVARCHAR(4000)

    DECLARE @firstName NVARCHAR(100)

    DECLARE @mainBody NVARCHAR(MAX)

    SELECT @mainBody = '<p>Welcome to the lovely batch mail we have here</p>

    <p>I think you will like it very much</p>

    <p>Bye then</p>

    <div id="Mysignature">'

    SELECT @batchSize = 8

    --test Data

    INSERT @tempemails(emailAddress)

    SELECT 'fred@fred.com' UNION

    SELECT 'bill@bill.com' UNION

    SELECT 'jane@jane.com' UNION

    SELECT 'norman@norman.com' UNION

    SELECT 'weeble@weeble.com'

    /*

    You might of course do

    INSERT @tempemails(emailAddress)

    SELECT DISTINCT emailAddress

    FROM myTable

    WHERE emailAddress IS NOT NULL

    */

    --see how many mails there are

    SELECT @totalMails = MAX(emailID) FROM @tempemails

    /**

    * compile the list of batches.

    * OK so the endID may go over the MaxID

    * but this with the below cursor this will not matter in the least

    **/

    INSERT @emailBatches(startID, endID)

    SELECT @batchSize*(t1.emailID-1)+1, @batchSize*(t1.emailID-1)+@batchSize

    FROM @tempemails t1

    WHERE @batchSize*(t1.emailID-1)+1 <= @totalMails

    DECLARE mailBatchCursor CURSOR FOR

    SELECT startID, endID

    FROM @emailBatches

    ORDER BY batchID

    OPEN mailBatchCursor

    FETCH NEXT FROM mailBatchCursor

    INTO @startID, @endID

    WHILE (@@fetch_status = 0)

    BEGIN

    --semi-colon separate the email addresses in the batch

    SELECT @emailAddresses = STUFF((SELECT ';' + emailAddress FROM @tempemails WHERE emailID BETWEEN @startID AND @endID FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)'),1,1,'')

    EXEC msdb.dbo.sp_send_dbmail

    @profile_name = 'Profile Name',

    @recipients=@cs_application_email,

    @blind_copy_recipients =@emailAddresses,

    @subject ='Subject Of The EMail',

    @body = @query,

    @body_format = @mainBody ;

    WAITFOR delay '00:10:00'

    FETCH NEXT FROM mailBatchCursor

    INTO @startID, @endID

    END

    CLOSE mailBatchCursor

    DEALLOCATE mailBatchCursor

    Using FOR XML again you can easily make a table out of any query to add:

    SELECT @table1 = '<h1>Look at the results below</h1><table><tr><th>col1</th><th>col2</th><th>col3</th></tr>' +

    (SELECT '<tr>' + '<td>' + col1 + '</td><td>' + col2 + '</td><td>' + col3 + '</td></tr>' FROM mytable WHERE myid = 5 FOR XML PATH(''),TYPE).value('.','VARCHAR(4000)')

    + '</table>'

    [font="Arial"]_______________________________________________________
    Change is inevitable... Except from a vending machine.[/font]

  • hello,

    the whole process of email is via email from SQL - if I get it!

    And if the email is external to SQL, for example Lotus Notes?

    Thank you.

  • You can send email from SQL to Outlook, Lotus Notes etc.I have implemented it for Microsoft Outlook.We need to know the relay server IP address while creating the Database Mail Configuration.

  • Outlook and Notes are clients (not sure if Notes server is called that).

    Mine is set to send via MS Exchange though any email server software such as sendmail would do. You could probably create a profile that sent via your gmail or hotmail accounts if you really wanted to.

    In the bad old days pre 2005 you needed client software of Outlook 2000 installed to send mails

    [font="Arial"]_______________________________________________________
    Change is inevitable... Except from a vending machine.[/font]

  • Thank you!

    I have to spend more time studying the capability to send emails via SQL. I have not had time.

    However, the typology of the Notes is: server and client. The Notes Server is equivalent to MS Exchange and Notes Client is equivalent to Outlook.

    Regards,

    JG

  • I remember when I was doing something along the same sort of lines before but McAfee Anti-Virus always flagged some emails as a virus

    Does your method get round this somehow?

  • One simple way is not to use Mcaffee. Sorry but that's just it.

    Besides if it is flagging a plain html email with no attachment as a virus then there is somethign severely wrong with the checker settings.

    It may flag it as spam but anyone subscribed to any news letter should also be prepared to add the sender to the white-list.

    Other than that, Using sensible, well formed, non derivative language in the subject and body is still one of the best ways to avoid getting flagged as a false positive by spam checkers though if you are mass mailing that will always increase your chances.

    [font="Arial"]_______________________________________________________
    Change is inevitable... Except from a vending machine.[/font]

  • The reason it flagged the generation of the email as a virus was due to McAfee thinking that some unreputable program had been creating HTML emails

    But i do agree I don't really like using McAfee there are better ones out there.

    It wasn't the fact that the reciever's email was flagged , but when the email was generated internally before it was sent

  • Ahh, I see where you are going there. If Mcafee was monitoring an email client and an external program tried to connect via the back end of the client then there may have been issues.

    Since this connects directly to the mail server, basically acting as a mail client in its own right then there should not be a problem there.

    The one issue I had when first sending email outside the company using database mail was that the profile was not using authentication and so Exchange would not allow relaying.

    Either your profile needs to connect using authentication or you need to add the SQL Server to the list of IP addresses allowed to relay within your mail server. If the mail server is external then you will almost certainly need to use authentication to be able to send at all.

    [font="Arial"]_______________________________________________________
    Change is inevitable... Except from a vending machine.[/font]

Viewing 15 posts - 1 through 15 (of 44 total)

You must be logged in to reply to this topic. Login to reply