Email two queries as Excel attachments in SQL Server stored procedure - sql-server

How can I email two queries as attachments in a SQL Server stored procedure?
Currently my code is only for one query. Thank you
ALTER PROCEDURE [dbo].[EmailDailyMembers]
AS
DECLARE #attach_query_result_as_file BIT = 1 -- yes, attach results as file
DECLARE #query_result_header BIT = 1 -- include column headers
DECLARE #query_result_separator CHAR(1) = char(9)
DECLARE #recordCount int
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'aaa#gmail.com',
#subject = 'Report1',
#query_attachment_filename = 'Report1.csv',
#attach_query_result_as_file = 1, -- attach as a file, csv in this case
#query_result_separator = #query_result_separator,
#query = 'USE Revenue2 SELECT * FROM [Membership Report]',
#query_result_header = 1,
#query_result_no_padding = 1,
#exclude_query_output = 1
END

Related

Scheduling a SQL Job using sp_add_jobschedule

I was trying to add a job using sp_add_jobschedule. I was also given a very good link yesterday where I got some clues on how to create a job. While creating the stored procedure I am getting an error:
Msg 102, Level 15, State 1, Procedure Usp_Create_job, Line 19 [Batch Start Line 81]
Incorrect syntax near ';'.
Msg 2812, Level 16, State 62, Line 103
Could not find stored procedure 'sp_add_jobstep'.
Msg 2812, Level 16, State 62, Line 118
Could not find stored procedure 'dbo.sp_add_jobserver'.
Msg 137, Level 15, State 2, Line 127
Must declare the scalar variable "#Frequency".
I have used the following code to create the Stored Procedure.
create procedure Usp_Create_job
as
begin
declare #SP_Name varchar(max)
declare #JobName varchar(max)
declare #Step varchar(max)
declare #ScheduleName varchar(max)
declare #Frequency int
declare #Interval int
declare #Time int
declare #StartDate int
EXEC dbo.sp_add_job
#job_name = N'#JobName', -- passing job name through input parameter while executing SP Usp_Create_job
#category_name=N'[Uncategorized (Local)]',
#owner_login_name=N'sa',
#notify_level_eventlog=0 ;
GO
EXEC sp_add_jobstep
#job_name = N'#JobName', --passing job name through input parameter while executing SP Usp_Create_job
#step_id = 1,
#step_name = N'#Step', --passing step name through input parameter while executing SP Usp_Create_job
#subsystem = N'TSQL',
#command = N'
-- actual query
exec #SP_Name',
#retry_attempts = 0,
#retry_interval = 0,
#on_success_action = 1,
#database_name=N'Test' ;
GO
EXEC dbo.sp_add_jobserver
#job_name = N'#JobName', --passing job name through input parameter while executing SP Usp_Create_job
#server_name = N'(local)' ;
GO
EXEC sp_add_jobschedule
#job_name = N'#JobName',
#name = N'test job schedule',
#enabled = 1, --enabled
#freq_type = #Frequency, -- on daily basis input value 4
#freq_interval = #Interval,
#freq_subday_type = 1, -- units between each exec: seconds
#freq_subday_interval = 0, -- number of units between each exec
#active_start_date= #StartDate,
#active_end_date=99991231,
#schedule_uid=N'8912aa53-ffe9-4f31-b6cb-9a8e2f1ee6e3'
end
I have reviewed the code couple of times but was unable to find the exact issue. Any improvements will also be appreciated.
There are a number of issues with your code.
You can't have GO in the middle of a procedure, it signifies the end of a batch and a procedure must be a single batch.
The procedures are located in msdb, and it seems you want to create the procedure in that database. You need to switch to that database first.
You haven't defined parameters properly, you have just made local variables.
You cannot pass parameters contained in quotes, as that just means it will be looked at as a bare string such as '#SP_Name'
Some data types are wrong.
#schedule_uid is an output parameter, you do not need to pass it.
You are not passing in #ScheduleName.
The value for #active_end_date should be in quotes.
USE msdb;
GO
CREATE OR ALTER PROCEDURE Usp_Create_job
#SP_Name sysname
#JobName sysname,
#Step sysname,
#ScheduleName sysname,
#Frequency int,
#Interval int,
#Time int,
#StartDate int
AS
DECLARE #command nvarchar(max) = #command = N'
-- actual query
exec ' + QUOTENAME(#SP_Name) + '
-- more commands here
'
EXEC sp_add_job
#job_name = #JobName, -- passing job name through input parameter while executing SP Usp_Create_job
#category_name = N'[Uncategorized (Local)]',
#owner_login_name = N'sa',
#notify_level_eventlog = 0;
EXEC sp_add_jobstep
#job_name = #JobName, --passing job name through input parameter while executing SP Usp_Create_job
#step_id = 1,
#step_name = #Step, --passing step name through input parameter while executing SP Usp_Create_job
#subsystem = N'TSQL',
#command = #command,
#retry_attempts = 0,
#retry_interval = 0,
#on_success_action = 1,
#database_name = N'Test';
EXEC dbo.sp_add_jobserver
#job_name = #JobName, --passing job name through input parameter while executing SP Usp_Create_job
#server_name = N'(local)' ;
EXEC sp_add_jobschedule
#job_name = #JobName,
#name = #ScheduleName,
#enabled = 1, --enabled
#freq_type = #Frequency, -- on daily basis input value 4
#freq_interval = #Interval,
#freq_subday_type = 1, -- units between each exec: seconds
#freq_subday_interval = 0, -- number of units between each exec
#active_start_date = #StartDate,
#active_end_date = '99991231';
GO
Exactly why you would want this rather than just using SSMS's nice graphical interface is a different question...

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.

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'

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

Resources