SQL Server msdb.dbo.sp_send_dbmail - sql-server

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...

Related

SQL Server : trying to send email using sp_send_dbmail

I'm trying to send attached file from query result using sp_send_dbmail
This is my code:
declare #q nvarchar(max)
select #q = 'select
case when s.mantype = ''99'' then ''Pre-sales''
when s.mantype = ''44'' then ''idk''
when s.mantype = ''77'' then ''Van sales''
when s.mantype = ''33'' then ''Delivery Person''
when s.mantype = ''55'' then ''Manager''
end ''mantype''
from man s '
begin
select #sub = 'Fire a Test ' + cast(convert(date,getdate()) as nvarchar)
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'my#email.com',
#profile_name = 'Profileone',
#subject = #sub,
#body ='TEST' ,
#body_format = 'TEXT',
#query_result_header = 1 ,
#query = #q,
#attach_query_result_as_file = 1,
#query_attachment_filename= 'Report.cvs';
end
but I'm getting an error :
Failed to initialize sqlcmd library with error number -2147467259
Note: when I remove the case in the query and select the column mantype, it runs, but when I add the case again, I get the above error.
It's been a while, I solved this issue by creating a view with the desired query.

Sending n HTML email with SQL Server with a preview

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;
*/

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.

Set dbo.sp_send_dbmail arguments to stored procedure return value?

I have stored procedure usp_emailRecipients that returns a semicolon-delimited list of email addresses. This is the list of email addresses that will receive an email sent using msdb.dbo.sp_send_dbmail.
How can I set the value of #recipients to the list returned in my stored procedure?
I cannot modify the stored procedure at the moment.
Something like:
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Bob Jones',
#recipients = 'exec usp_emailRecipients',
#subject = 'Test email',
#execute_query_database = 'Sales',
#query = N'select * from sales',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Sales.txt'
Thanks.
The way you have this coded it will send a string literal as the value for recipients. This is not how this works. The way to do this is to use an OUTPUT variable in usp_emailRecipients. This will require a change in your procedure so you are using an OUTPUT parameter. Then you populate the variable like this.
declare #recipientList varchar(max)
exec usp_emailRecipients #recipientList OUTPUT
You would do this prior to calling sp_send_dbmail.
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Bob Jones',
#recipients = #recipientList,
#subject = 'Test email',
#execute_query_database = 'Sales',
#query = N'select * from sales',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Sales.txt'
--EDIT--
Since you say you can not modify your stored procedure you are going to have to do something like use FOR XML to create a delimited list from the result set of your procedure.
This code is 100% untested because we have nothing to work with but it should be pretty close.
create table #EmailList
(
EmailAddress varchar(255)
)
insert #EmailList
exec usp_emailRecipients
declare #recipientList varchar(max)
select #recipientList = STUFF((select ';' + EmailAddress
from #EmailList
FOR XML PATH('')), 1, 1, '')
Then you can send the email like I posted above.
Do you have the flexibility to turn the usp_emailRecipients procedure into a scalar function, lets say udf_emailRecipients? If so, you can then do the following:
Declare #recipients as varchar(max)
Select #recipients= udf_emailRecipients();
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Bob Jones',
#recipients,
#subject = 'Test email',
#execute_query_database = 'Sales',
#query = N'select * from sales',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Sales.txt'

How to concatenate string when setting a parameter in Transact-SQL

First question here and is the following. I wrote the following code and everything works fine:
DECLARE #subject NVARCHAR(100)
SET #subject = 'Report executed on ' + CONVERT(VARCHAR(12), GETDATE(), 107)
SELECT #subject
Result: Report executed on Aug 17, 2012
but when trying to concatenate the previous string while setting the parameter of msdb.dbo.sp_send_dbmail procedure, it fails
EXEC msdb.dbo.sp_send_dbmail #profile_name='XXX',
#recipients='XXXX#XXXXX.com',
#subject = 'Report executed on ' + CONVERT(VARCHAR(12), GETDATE(), 107),
#body= #tableHTML,
#body_format = 'HTML';
I know I could declare and send a variable to the parameter but I would like to understand why it fails when concatenating directly in the parameter. thank you for your time and knowledge
Parameter values to T-SQL stored procedures cannot be expressions. They need to be either a constant or a variable.
From MSDN - Specify Parameters:
The parameter values supplied with a procedure call must be constants
or a variable; a function name cannot be used as a parameter value.
Variables can be user-defined or system variables such as ##spid.
You need to do:
DECLARE #Sub nvarchar(100);
SET #Sub = 'Report executed on ' + CONVERT(VARCHAR(12), GETDATE(), 107);
EXEC msdb.dbo.sp_send_dbmail #profile_name='XXX',
#recipients='XXXX#XXXXX.com',
#subject = #Sub,
#body= #tableHTML,
#body_format = 'HTML';

Resources