Sending n HTML email with SQL Server with a preview - sql-server

I have coded an HTML email to send out through SQL Server. It is currently working however it automatically sends out. I am wondering if there is a way for me to review the email in the default client before it gets sent out?
EXEC msdb.dbo.sp_send_dbmail #recipients = 'test#email.com'
, #subject = 'Action Item Test', #body = #body, #body_format='HTML', #reply_to = 'noreply#myserver.com'

I had same request while ago and I put the e-mails to table and sent an notification to reviewer.
It is not my area but if you have e-mail security services you can put your e-mail(which you use in msdb profile) as spam, you can review it and reject/release with no any other extra process. I have used mimecast. It hold all suspected e-mail on the server until you release them.
In my opinion it is not manageable if you do it manually, but if you still want to do it I have some script to you :
Basically : Create a table and put all e-mail details to that table which you want to review. It will send notification to you. If you are happy execute the latest procedure to release the e-mail.
--Create Reviews table
IF OBJECT_ID('EMailReviews') IS NOT NULL
DROP TABLE EMailReviews;
CREATE TABLE EMailReviews
(
Id INT NOT NULL IDENTITY(1,1)
--ProfileName?
,Recipients VARCHAR(MAX)
--,CopyRecipients VARCHAR(MAX)
,EMailSubject NVARCHAR(255)
,Body NVARCHAR(MAX)
,BodyFormat VARCHAR(20)
,ReplyTo VARCHAR(MAX)
,DateReceived DATETIME NOT NULL DEFAULT(SYSDATETIME())
,DateReviewed DATETIME
,Processed BIT NOT NULL DEFAULT(0)
);
--Create Procedure to insert the e-mail to review table and send notification to you.
IF OBJECT_ID('P_PutEMailToReviewQueue') IS NOT NULL
DROP PROCEDURE P_PutEMailToReviewQueue;
GO
CREATE PROCEDURE P_PutEMailToReviewQueue
#Recipients VARCHAR(MAX)
--,#CopyRecipients VARCHAR(MAX)
,#EMailSubject NVARCHAR(255)
,#Body NVARCHAR(MAX)
,#BodyFormat VARCHAR(20)
,#ReplyTo VARCHAR(MAX)
AS
DECLARE #Reviewer VARCHAR(100)='revieweremail#email.com' /*!!Put your e-mail to review!!*/
DECLARE #ReviewerEMailSubject NVARCHAR(MAX)=''
DECLARE #ReviewerEMailBody NVARCHAR(MAX)=''
--Put validations if necessary
INSERT INTO EMailReviews(Recipients,EMailSubject,Body,BodyFormat,ReplyTo)
VALUES (#Recipients,#EMailSubject,#Body,#BodyFormat,#ReplyTo)
DECLARE #Id VARCHAR(100)=CAST(SCOPE_IDENTITY()AS VARCHAR)
SET #ReviewerEMailBody = 'E-Mail Information below:'
+'<br>'
+'ID='+#Id
+'<br>'
+'Subject:'+ISNULL(#EMailSubject,'')
+'<br>'
+'Body:'+ISNULL(#Body,'')
+'<br>'
+'Recipients:'+ISNULL(#Recipients,'')
+'<br>'
+'ReplyTo:'+ISNULL(#ReplyTo,'')
+'<br>'
+'<br>'
+'<br>'
+'<br>'
+'After your review if you want to release the e-mail you need to run following script:'
+'<br>'
+'P_ReleaseEmail #Id ='+#Id
SET #ReviewerEMailSubject = 'Number '+#Id+' e-mail has been recieved. Review required!'
EXEC msdb.dbo.sp_send_dbmail
#recipients = #Reviewer
, #subject = #ReviewerEMailSubject
, #body = #ReviewerEMailBody
, #body_format ='HTML'
GO
/*
P_PutEMailToReviewQueue
#Recipients ='test#test.com'
,#EMailSubject ='Action Item Test'
,#Body ='BLA BLA'
,#BodyFormat ='HTML'
,#ReplyTo ='noreply#test.com'
*/
--Create procedure to release the e-mail.
IF OBJECT_ID('P_ReleaseEmail') IS NOT NULL
DROP PROCEDURE P_ReleaseEmail;
GO
CREATE PROCEDURE P_ReleaseEmail
#Id INT
AS
DECLARE
#Recipients VARCHAR(MAX)
--,#CopyRecipients VARCHAR(MAX)
,#EMailSubject NVARCHAR(255)
,#Body NVARCHAR(MAX)
,#BodyFormat VARCHAR(20)
,#ReplyTo VARCHAR(MAX)
SELECT #Recipients=Recipients
,#EMailSubject=EMailSubject
,#Body=Body
,#BodyFormat=BodyFormat
,#ReplyTo=ReplyTo
FROM EMailReviews
WHERE Id=#Id
EXEC msdb.dbo.sp_send_dbmail
#recipients = #Recipients
, #subject = #EMailSubject
, #body = #Body
, #body_format = #BodyFormat
, #reply_to = #ReplyTo
UPDATE EMailReviews SET DateReviewed=GETDATE()
,Processed=1
WHERE Id=#Id
GO
/*
P_ReleaseEmail
#Id =1;
select * from EMailReviews;
*/

Related

SQL Server - adding nvarchar variable to email with html formatting

I just can't see what I'm doing wrong but it's probably a simple issue.
I use sp_send_dbmail to send an email notification to users. The body of the email is formatted with html.
When I do tests, the body is blank. I've narrowed it down to the #Name variable. If I add a simple string like 'John' then the body is not blank, but I'm doing something wrong with the #Name variable.
I would think the CAST of #Name is unnecessary, but I've just been trying different things to no avail.
How do I incorporate #Name in a correct way?
Below is the code with parts of the irrelevant html left out to shorten it:
Alter Proc [dbo].[SendPayslipEmail]
(#TVP EmailAddressTableType READONLY,
#Period NVARCHAR(50),
#Message NVARCHAR(MAX))
as
begin
DECLARE #ResTag INT
DECLARE #Email_Address VARCHAR(150)
DECLARE #emailHTML NVARCHAR(MAX) ;
DECLARE #Subject NVARCHAR(50);
DECLARE #Name NVARCHAR(50);
DECLARE #LoginURL NVARCHAR(50);
SET #Subject = (Select [Value] from [CustomerEmailSettings] where [Setting] = 'Payslip Email Subject')
SET #LoginURL = (Select [Value] from [CustomerEmailSettings] where [Setting] = 'LoginURL')
DECLARE cursorSendEmail CURSOR
FOR SELECT [Resource Tag],[E-mail Address] FROM #TVP;
OPEN cursorSendEmail
FETCH NEXT FROM cursorSendEmail INTO #ResTag,#Email_Address;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Name = CAST((SELECT [Display Name] FROM DisplayName(#ResTag)) AS NVARCHAR(50))
SET #emailHTML =
N'<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">'
+N'<head>'
<!-- More html -->
+N'<p class=MsoNormal><b><span style=''color:#4485B8''>Dear '
+#Name
+N',<o:p></o:p></span></b></p>'
<!-- More html -->
+N'</html>'
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'PayslipEmails',
#recipients = #Email_Address,
#body = #emailHTML,
#body_format = 'HTML',
#subject = #Subject;
FETCH NEXT FROM cursorSendEmail INTO #ResTag,#Email_Address;
END
CLOSE cursorSendEmail
DEALLOCATE cursorSendEmail
end

SQL query results to mail- Receiving Error formatting query, probably invalid parameters error

I am trying to send the invalid codes to mail. However when I execute the job for stored procedure, it completed fine and did not send any email. When I execute the query alone, I am getting the results. Did I miss any configuration setup?
CREATE PROCEDURE sp_Send_Email_Invalid_code
#MONTH AS int = 0
AS
BEGIN
DECLARE #Email_Subject AS nvarchar(250) = 'Codes Missing in master table';
DECLARE #Email_Receipients_To AS nvarchar(max) = 'xxx.yyy.com';
DECLARE #IsUseEmailConfig AS bit = 1;
DECLARE #Email_Category AS nvarchar(250);
SET #IsUseEmailConfig = 0
SET #Email_Category = 'Codes Missing in master table'
SELECT DISTINCT CODE
INTO #temp_1
FROM tblRegCode nolock
SELECT
*
FROM
#temp_1
DECLARE #Query nvarchar(max);
SET #Query = 'SELECT * FROM #temp_1';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'psmEmailer',
#recipients = 'xxx.yyy.com',
#query = #Query,
#subject = 'Missing codes',
#attach_query_result_as_file = 1 ;
DROP TABLE #temp_1;
END
My SQL Server agent job is
DECLARE #MONTH AS int = 0
DECLARE #dt datetime = GETDATE()
SET #MONTH = DATEPART(mm, DATEADD(mm, -1, #dt))
EXEC sp_Send_Email_Invalid_code #MONTH
This is difficult to answer because there isn't anything obvious in the code above that is coursing the issue. Therefore the problem must be else where. My thoughts are 1) your query result set isn't returning anything. 2) Your email config is correct meaning the email can't be sent.
For number 1, we can't resolve this without checking your data, so moving on.
For number 2, try sending a simple email from the SQL instance using the send mail procedure in isolation. Like this:
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'you#somewhere.com',
#subject = 'Send Mail Test',
#body = 'Testing',
#body_format = 'HTML';
Then is you don't receive an email check the failure logs in MSDB with the following query.
USE [msdb]
GO
SELECT
l.[description] AS 'Error failure',
f.[recipients],
f.[subject],
f.[sent_date],
f.[body],
f.[body_format]
FROM
[dbo].sysmail_faileditems f
JOIN [dbo].sysmail_event_log l
ON f.[mailitem_id] = l.[mailitem_id]
ORDER BY
f.[sent_date] DESC
If you do receive the test email I'd suggest the problem is with your query results that your trying to attach.
Just another thought. You may also need to use the param #execute_query_database and #query_attachment_filename.
Check https://msdn.microsoft.com/en-us/library/ms190307.aspx for details.
So, you can make from your SP just this:
CREATE PROCEDURE sp_Send_Email_Invalid_code
#MONTH AS int
AS
BEGIN
DECLARE #Query nvarchar(max) = 'SELECT [CODE ] FROM tblRegCode nolock';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'psmEmailer',
#recipients = 'xxx.yyy.com',
#query = #Query,
#subject = 'Codes Missing in master table',
#attach_query_result_as_file = 1 ;
END
GO
In the SP you are not using #MONTH, why?
Try to add WITH EXECUTE AS OWNER in your SP, and run it via job.

SQL Server msdb.dbo.sp_send_dbmail

I want to publish some query results in the e-mail in a structured format. I'm using the #body_format as 'HTML'.
I want to do like:
Declare #processed_rows int
declare #Sourcetype varchar(100)
select #sourcetype = (some SQL query)
select #processed_rows = (some SQL query)
exec msdb.dbo.sp_send_dbmail
#body='some HTML' ,
#subject = 'IGD-DEVELOPMENT SERVER UPDATED',
#profile_name = 'IGDMail',
#recipients = ' abhisheks#exzeo.com
When I'm executing msdb.dbo.sp_send_dbmail, I want to pass these variables in the #body argument of stored procedure and use them in the final email, please help to achieve this?
You'll need to declare another variable to hold your HTML code:
DECLARE #HTML NVARCHAR(MAX)
SET #HTML = 'SOME HTML HERE' + CAST(PROCESSED_ROWS AS VARCHAR) + 'SOME MORE HTML' + #SOURCETYPE
EXEC MSDB.DBO.SP_SEND_DBMAIL
#BODY = #HTML
, #BODY_FORMAT = 'HTML'
ETC.....
You get the idea...

Sql Server stored procedure that sends emails stored in table

I currently have a stored procedure that is sending out emails, but it's getting an error. Also, is there some error checking that I can put in place to ensure the email is sent? I insert data into a table called outbound_email_queue the table is defined as:
CREATE TABLE dbo.outbound_email_queue(
email_id int IDENTITY(1,1) NOT NULL,
out_type varchar(3) NOT NULL,
send_time datetime NULL,
from_addr varchar(100) NOT NULL,
to_addr varchar(254) NOT NULL,
reply_addr varchar(60) NULL,
subject varchar(254) NOT NULL,
letter_body varchar(8000) NOT NULL
The stored procedure I'm using is below.
It gets an error on the Commit statement.
It seems to do the delete, even though I leave out the commit. Even if I get it to execute the procedure, it empties the table but it doesn't seem to send the emails.
CREATE PROCEDURE [dbo].[uspEmail]
as
BEGIN
Declare #email_id as bigint
Declare #email_type as nvarchar(3)
Declare #from_add as nvarchar(100)
Declare #to_add as nvarchar(254)
Declare #reply_add as nvarchar(60)
Declare #email_prof as nvarchar(80)
Declare #MySubject as nvarchar(254)
Declare #Message as nvarchar(MAX)
Declare EmailCursor CURSOR FAST_FORWARD FOR
Select email_id, out_type, from_addr, to_addr, reply_addr, subject,
letter_body from outbound_email_queue
set #email_prof = (select email_profile from system_file)
OPEN EmailCursor
FETCH NEXT FROM EmailCursor INTO #email_id, #email_type, #from_add, #to_add,
#reply_add, #MySubject, #Message
WHILE ##FETCH_STATUS = 0 BEGIN -- send the email
EXEC msdb.dbo.sp_send_dbmail
#profile_name = #email_prof,
#recipients = #to_add,
#reply_to = #reply_add,
#body_format = 'HTML',
#from_address = #from_add,
#subject = #MySubject,
#body = #Message
DELETE FROM OUTBOUND_EMAIL_QUEUE WHERE EMAIL_ID = #email_id
FETCH NEXT FROM EmailCursor INTO #email_id, #email_type, #from_add, #to_add,
#reply_add, #MySubject, #Message
END CLOSE EmailCursor
DEALLOCATE EmailCursor
COMMIT
END
GO

Sending Database emails to multiple recipients while tweaking the body

i need to send emails to approx, twenty recipients each day, i build a temp table with two columns
Email_Body
Email_address
there are at max 50 rows in the table each day
i want to loop though this table and execute sp_send_email
EXEC msdb.dbo.sp_send_dbmail
#Profile_name = 'DBA',
#recipients = #email_address,
#body = #Email_Body,
#subject = 'Test Email'
is there a way to do this without a cursor?
any links to an example would be appreciated, i have searched and can't find such an example. i am sure it is a very common process.
You might try the solution found here.
I think this code sample would help:
while (#count <=(select COUNT(*) from #table))
begin
select top 1 #Recepient_Email=Emp_Email,#mailBody=body from #table where ID=#count
EXEC msdb.dbo.sp_send_dbmail
#profile_name='Profile1',
#recipients=#Recepient_Email,
#subject = 'This is subject of test Email'
#body = #mailbody,
#body_format = 'HTML'
set #count =#count +1
END
--Email Campaign.
declare #HtmlModel varchar(max)
declare #HtmlBody varchar(max)
SELECT #HtmlModel = EmailBody
FROM EmailCampaigns
WHERE ID = 1
--a different process will have created an awesome looking well formed html with our known
--placeholders for [FirstName] [LastName] [Phone] [Email] that might ber substituted for individualization
--PRINT #HtmlModel;
SET #HtmlBody=''
declare
#mailID int,
#id int,
#first varchar(64),
#last varchar(64),
#phone varchar(64),
#email varchar(64)
declare c1 cursor for
--################################
SELECT ID,
ISNULL(FirstName,'Friend') AS FirstName,
ISNULL(LastName,'') AS LastName,
ISNULL(Phone,''),
ISNULL(Email ,'')
--the row_number is so that if i put your name in the database five times, you only get a single email.
FROM (
select ROW_NUMBER() over (partition by email order by email,len(firstname)desc,len(lastname)desc ) AS RW, *
from RawContacts
where email <> '') x
WHERE RW = 1
--this WHERe stays in place until we are ready to go LIVE with the email.
and email IN('lowell#somedomain.com','otherReviewer#somedomain.com')
--################################
open c1
fetch next from c1 into #id,#first,#last,#phone,#email
While ##fetch_status <> -1
begin
SET #HtmlBody = REPLACE(#HTMLModel,'[FirstName]',#first)
SET #HtmlBody = REPLACE(#HtmlBody,'[LastName]', #last)
SET #HtmlBody = REPLACE(#HtmlBody,'[Phone]', #phone)
SET #HtmlBody = REPLACE(#HtmlBody,'[Email]', #email)
--EXEC msdb.dbo.sp_send_dbmail
#Profile_name = 'Database Mail Profile Name',
#recipients=#email,
#subject = 'Our non profits Call for Volunteers',
#body = #HtmlBody,
#body_format = 'HTML',
#mailitem_id = #mailID OUTPUT
--#body_format = 'TEXT'
INSERT INTO CampaignRecipients(Campaign,RawContactID,MailSentID,MailSentDate)
SELECT 1,#id,#mailID,GETDATE()
fetch next from c1 into #id,#first,#last,#phone,#email
end
close c1
deallocate c1
GO

Resources