How to execute sp_send_dbmail while limiting permissions - sql-server-2005

Is there a way to provide access to users in my database to execute msdb.dbo.sp_send_dbmail without needing to add them to the MSDB database and the DatabaseMailUserRole?
I've tried this:
ALTER PROCEDURE [dbo].[_TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
WITH EXECUTE AS OWNER
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail #profile_name = N'myProfile',
#recipients = #To, #subject = #Subject, #body = #Body
END
But I get this error:
The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.
Thanks!

Your approach is OK, but your wrapper proc must be in the msdb database.
Then, you execute "EXEC msdb.dbo._TestSendMail"
This still leave the issue of permissions on dbo._TestSendMail in msdb.
But public/EXECUTE will be enough: it only exposes the 3 parameters you need.
If in doubt, add WITH ENCRYPTION. This is good enough to stop anyone without sysadmin rights viewing the code
USE msdb
GO
CREATE PROCEDURE [dbo].[_TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
-- not needec WITH EXECUTE AS OWNER
AS
BEGIN
EXEC dbo.sp_send_dbmail #profile_name = N'myProfile',
#recipients = #To, #subject = #Subject, #body = #Body
END

You actually can do it with a certificate signed stored procedure and it doesn't have to be in msdb to do so:
CREATE DATABASE TestDBMail
GO
USE [TestDBMail]
GO
CREATE PROCEDURE [dbo].[TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
WITH EXECUTE AS OWNER
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = N'Database Mail Profile',
#recipients = #To,
#subject = #Subject,
#body = #Body
END
GO
-- This should fail
EXECUTE [dbo].[TestSendMail] 'someemail#domain.com', 'test', 'body'
-- Create a certificate to sign stored procedures with
CREATE CERTIFICATE [DBMailCertificate]
ENCRYPTION BY PASSWORD = '$tr0ngp#$$w0rd'
WITH SUBJECT = 'Certificate for signing TestSendMail Stored Procedure';
GO
-- Backup certificate so it can be create in master database
BACKUP CERTIFICATE [DBMailCertificate]
TO FILE = 'd:\Backup\DBMailCertificate.CER';
GO
-- Add Certificate to Master Database
USE [master]
GO
CREATE CERTIFICATE [DBMailCertificate]
FROM FILE = 'd:\Backup\DBMailCertificate.CER';
GO
-- Create a login from the certificate
CREATE LOGIN [DBMailLogin]
FROM CERTIFICATE [DBMailCertificate];
GO
-- The Login must have Authenticate Sever to access server scoped system tables
-- per http://msdn.microsoft.com/en-us/library/ms190785.aspx
GRANT AUTHENTICATE SERVER TO [DBMailLogin]
GO
-- Create a MSDB User for the Login
USE [msdb]
GO
CREATE USER [DBMailLogin] FROM LOGIN [DBMailLogin]
GO
-- Add msdb login/user to the DatabaseMailUserRole
EXEC msdb.dbo.sp_addrolemember #rolename = 'DatabaseMailUserRole', #membername = 'DBMailLogin';
GO
USE [TestDBMail]
GO
-- Sign the procedure with the certificate's private key
ADD SIGNATURE TO OBJECT::[TestSendMail]
BY CERTIFICATE [DBMailCertificate]
WITH PASSWORD = '$tr0ngp#$$w0rd';
GO
-- This will succeed
EXECUTE [dbo].[TestSendMail] 'someemail#domain.com', 'test', 'body'
/*
-- Cleanup
USE [msdb]
GO
DROP USER [DBMailLogin]
GO
USE [master]
GO
DROP LOGIN [DBMailLogin]
DROP CERTIFICATE [DBMailCertificate]
DROP DATABASE [TestDBMail]
-- Delete the certificate backup from disk
*/

One possible solution is to encapsulate the mailing as a stored procedure e.g. mail_error_as_MAILER (wich you will later call)
and another stored procedure
e.g.
ALTER PROCEDURE [dbo].[mail_error](#error_ID int)
SET NOCOUNT ON
declare #rc int
declare #object int
declare #src varchar(255)
declare #desc varchar(255)
declare #osql_cmd varchar(1000)
-- create shell object
exec #rc = sp_oacreate 'wscript.shell', #object out
if #rc0
begin
exec sp_oageterrorinfo #object, #src out, #desc out
return
END
DECLARE #user VARCHAR(50)
DECLARE #password VARCHAR(50)
DECLARE #database VARCHAR(50)
DECLARE #server VARCHAR(50)
DECLARE #sql varchar(200)
SET #user=MAILER,#password=XXXXXX,#database=XXXXXX,#server=XXXXX
SET #sql= 'EXEC mail_ERROR_as_MAILER #error_ID=' + CAST(#error_id as varchar(10))
set #osql_cmd='osql -U'+#user+' -P'+#password+' -d'+#database+' -S"'+#server+'" -Q"'
+#sql+'"'
exec #rc= sp_oamethod #object, 'run', null, #osql_cmd
--print #rc
if #rc0
begin
exec sp_oageterrorinfo #object, #src out, #desc out
return
end
-- destroy shell object
exec sp_oadestroy #object
But this requires:
* hardcoding password (make sure users cannot view definition of stored procedure ...)
* giving users access to sp_oacreate etc... (opens up other security problems e.g. DOS)
that way they can only use the mail the way you want to without giving them permission to mail other things.
Or safer,
let users put mail in some kind of mail_queue(wich you can control what they can put in) and have an agent acount send these mails periodically
Or: give them permission to mail but take a big club with rusted spikes on abuse

Related

Why doesn't a SQL trigger have permissions to use e-mail? [duplicate]

Is there a way to provide access to users in my database to execute msdb.dbo.sp_send_dbmail without needing to add them to the MSDB database and the DatabaseMailUserRole?
I've tried this:
ALTER PROCEDURE [dbo].[_TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
WITH EXECUTE AS OWNER
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail #profile_name = N'myProfile',
#recipients = #To, #subject = #Subject, #body = #Body
END
But I get this error:
The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.
Thanks!
Your approach is OK, but your wrapper proc must be in the msdb database.
Then, you execute "EXEC msdb.dbo._TestSendMail"
This still leave the issue of permissions on dbo._TestSendMail in msdb.
But public/EXECUTE will be enough: it only exposes the 3 parameters you need.
If in doubt, add WITH ENCRYPTION. This is good enough to stop anyone without sysadmin rights viewing the code
USE msdb
GO
CREATE PROCEDURE [dbo].[_TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
-- not needec WITH EXECUTE AS OWNER
AS
BEGIN
EXEC dbo.sp_send_dbmail #profile_name = N'myProfile',
#recipients = #To, #subject = #Subject, #body = #Body
END
You actually can do it with a certificate signed stored procedure and it doesn't have to be in msdb to do so:
CREATE DATABASE TestDBMail
GO
USE [TestDBMail]
GO
CREATE PROCEDURE [dbo].[TestSendMail]
(
#To NVARCHAR(1000),
#Subject NVARCHAR(100),
#Body NVARCHAR(MAX)
)
WITH EXECUTE AS OWNER
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = N'Database Mail Profile',
#recipients = #To,
#subject = #Subject,
#body = #Body
END
GO
-- This should fail
EXECUTE [dbo].[TestSendMail] 'someemail#domain.com', 'test', 'body'
-- Create a certificate to sign stored procedures with
CREATE CERTIFICATE [DBMailCertificate]
ENCRYPTION BY PASSWORD = '$tr0ngp#$$w0rd'
WITH SUBJECT = 'Certificate for signing TestSendMail Stored Procedure';
GO
-- Backup certificate so it can be create in master database
BACKUP CERTIFICATE [DBMailCertificate]
TO FILE = 'd:\Backup\DBMailCertificate.CER';
GO
-- Add Certificate to Master Database
USE [master]
GO
CREATE CERTIFICATE [DBMailCertificate]
FROM FILE = 'd:\Backup\DBMailCertificate.CER';
GO
-- Create a login from the certificate
CREATE LOGIN [DBMailLogin]
FROM CERTIFICATE [DBMailCertificate];
GO
-- The Login must have Authenticate Sever to access server scoped system tables
-- per http://msdn.microsoft.com/en-us/library/ms190785.aspx
GRANT AUTHENTICATE SERVER TO [DBMailLogin]
GO
-- Create a MSDB User for the Login
USE [msdb]
GO
CREATE USER [DBMailLogin] FROM LOGIN [DBMailLogin]
GO
-- Add msdb login/user to the DatabaseMailUserRole
EXEC msdb.dbo.sp_addrolemember #rolename = 'DatabaseMailUserRole', #membername = 'DBMailLogin';
GO
USE [TestDBMail]
GO
-- Sign the procedure with the certificate's private key
ADD SIGNATURE TO OBJECT::[TestSendMail]
BY CERTIFICATE [DBMailCertificate]
WITH PASSWORD = '$tr0ngp#$$w0rd';
GO
-- This will succeed
EXECUTE [dbo].[TestSendMail] 'someemail#domain.com', 'test', 'body'
/*
-- Cleanup
USE [msdb]
GO
DROP USER [DBMailLogin]
GO
USE [master]
GO
DROP LOGIN [DBMailLogin]
DROP CERTIFICATE [DBMailCertificate]
DROP DATABASE [TestDBMail]
-- Delete the certificate backup from disk
*/
One possible solution is to encapsulate the mailing as a stored procedure e.g. mail_error_as_MAILER (wich you will later call)
and another stored procedure
e.g.
ALTER PROCEDURE [dbo].[mail_error](#error_ID int)
SET NOCOUNT ON
declare #rc int
declare #object int
declare #src varchar(255)
declare #desc varchar(255)
declare #osql_cmd varchar(1000)
-- create shell object
exec #rc = sp_oacreate 'wscript.shell', #object out
if #rc0
begin
exec sp_oageterrorinfo #object, #src out, #desc out
return
END
DECLARE #user VARCHAR(50)
DECLARE #password VARCHAR(50)
DECLARE #database VARCHAR(50)
DECLARE #server VARCHAR(50)
DECLARE #sql varchar(200)
SET #user=MAILER,#password=XXXXXX,#database=XXXXXX,#server=XXXXX
SET #sql= 'EXEC mail_ERROR_as_MAILER #error_ID=' + CAST(#error_id as varchar(10))
set #osql_cmd='osql -U'+#user+' -P'+#password+' -d'+#database+' -S"'+#server+'" -Q"'
+#sql+'"'
exec #rc= sp_oamethod #object, 'run', null, #osql_cmd
--print #rc
if #rc0
begin
exec sp_oageterrorinfo #object, #src out, #desc out
return
end
-- destroy shell object
exec sp_oadestroy #object
But this requires:
* hardcoding password (make sure users cannot view definition of stored procedure ...)
* giving users access to sp_oacreate etc... (opens up other security problems e.g. DOS)
that way they can only use the mail the way you want to without giving them permission to mail other things.
Or safer,
let users put mail in some kind of mail_queue(wich you can control what they can put in) and have an agent acount send these mails periodically
Or: give them permission to mail but take a big club with rusted spikes on abuse

Create user with roles inside stored procedure

I want to create users with roles inside stored procedure. I tried plain query it didn't work, probably because of GO, then I tried to put that inside stored procedure, that didn't wok because of GO either. I tried to put new line character inside dynamic query, that didn't work either. Can anyone help?
create PROCEDURE dbo.CreateUser
AS
BEGIN
/*** Creating User ***/
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
CREATE USER [PRODUCTION\user1] FOR LOGIN [PRODUCTION\user1] WITH DEFAULT_SCHEMA=[dbo]
GO
sp_addrolemember #rolename = ''db_owner'', #membername = ''PRODUCTION\user1''
GO
CREATE USER [PRODUCTION\user2] FOR LOGIN [PRODUCTION\user2] WITH DEFAULT_SCHEMA=[dbo]
GO
sp_addrolemember #rolename = ''db_owner'', #membername = ''PRODUCTION\user2''
GO'
/*** Creating User ***/
EXEC(#SQL)
END
Personally, I would do this:
CREATE PROCEDURE dbo.CreateUser
AS
BEGIN
/*** Creating User ***/
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = N'CREATE USER [PRODUCTION\user1] FOR LOGIN [PRODUCTION\user1] WITH DEFAULT_SCHEMA=[dbo];' + NCHAR(13) + NCHAR(10) +
N'CREATE USER [PRODUCTION\user2] FOR LOGIN [PRODUCTION\user2] WITH DEFAULT_SCHEMA=[dbo];';
--PRINT #SQL; --Your debugging best friend
EXEC sp_executesql #SQL;
SET #SQL = N'ALTER ROLE db_owner ADD MEMBER [PRODUCTION\user1];' + NCHAR(13) + NCHAR(10) +
N'ALTER ROLE db_owner ADD MEMBER [PRODUCTION\user2];';
--PRINT #SQL; --Your debugging best friend
EXEC sp_executesql #SQL;
END
This gets rid of the sp_addrolemember procedure, which is deprecated. It also splits the creation and memberships into 2 separate batches, to ensure that the users have indeed been created.

Primavera switching computers master.mdf replace not working

I'm using primavera with a SQL Server database.
I switched computers, so I took with me the primavera_DAT, primavera_LOG files, then I installed primavera on the other computer and replaced the above files.
The issue is, whenever I enter primavera, I can establish the connection, but can not login and it is telling me the username and password are wrong.
I did some research and I found out that the usernames and passwords are stored in the master.mdf file.
I also have the master.mdf from the other computer, however when I replace them, I am getting the error whenever I start the SQL Server service from services.
How can I recreate the username or pass for the users (privuser, pubuser) that is, get the new master.mdf like the old one ??
You can recreate the necessary logins from the users of your database using sp_change_users_login with 'Auto_fix' which will map existing logins and create new logins if they don't exist. The password has to be given and changed later for not existing logins.
Declare #Membername varchar(255)
Declare #SQl Varchar(8000)
Select #SQL=''
Create Table #tmp
(
DbRole varchar (255),
Membername varchar (255),
MemberSid uniqueIdentifier
)
insert into #tmp exec sp_helprolemember
Delete from #tmp where Membername in ('sa','dbo','guest')
Delete from #tmp where Membername like ('db_%')
DECLARE P_cursor CURSOR FOR
SELECT Distinct Membername from #tmp
OPEN P_cursor
FETCH NEXT FROM P_cursor
INTO #Membername
WHILE ##FETCH_STATUS = 0
BEGIN
Select #SQL=#SQL + 'exec sp_change_users_login ''Auto_Fix'', ''' + #Membername +''' , NULL, '+'''B3r12-3x$098f6''' +Char(13)+Char(10)
FETCH NEXT FROM P_cursor
INTO #Membername
END
CLOSE P_cursor
DEALLOCATE P_cursor
Drop Table #tmp
--Print #SQL
Exec (#SQL)

How to send email from SQL Server?

How can I send an email using T-SQL but email address is stored in a table? I want to loop through the table and be able to send email. I cannot find a good example of doing this so far.
Step 1) Create Profile and Account
You need to create a profile and account using the Configure Database Mail Wizard which can be accessed from the Configure Database Mail context menu of the Database Mail node in Management Node. This wizard is used to manage accounts, profiles, and Database Mail global settings.
Step 2)
RUN:
sp_CONFIGURE 'show advanced', 1
GO
RECONFIGURE
GO
sp_CONFIGURE 'Database Mail XPs', 1
GO
RECONFIGURE
GO
Step 3)
USE msdb
GO
EXEC sp_send_dbmail #profile_name='yourprofilename',
#recipients='test#Example.com',
#subject='Test message',
#body='This is the body of the test message.
Congrates Database Mail Received By you Successfully.'
To loop through the table
DECLARE #email_id NVARCHAR(450), #id BIGINT, #max_id BIGINT, #query NVARCHAR(1000)
SELECT #id=MIN(id), #max_id=MAX(id) FROM [email_adresses]
WHILE #id<=#max_id
BEGIN
SELECT #email_id=email_id
FROM [email_adresses]
set #query='sp_send_dbmail #profile_name=''yourprofilename'',
#recipients='''+#email_id+''',
#subject=''Test message'',
#body=''This is the body of the test message.
Congrates Database Mail Received By you Successfully.'''
EXEC #query
SELECT #id=MIN(id) FROM [email_adresses] where id>#id
END
Posted this on the following link http://ms-sql-queries.blogspot.in/2012/12/how-to-send-email-from-sql-server.html
You can send email natively from within SQL Server using Database Mail. This is a great tool for notifying sysadmins about errors or other database events. You could also use it to send a report or an email message to an end user.
The basic syntax for this is:
EXEC msdb.dbo.sp_send_dbmail
#recipients='user#yourdomain.com',
#subject='Testing Email from SQL Server',
#body='<p>It Worked!</p><p>Email sent successfully</p>',
#body_format='HTML',
#from_address='Sender Name <sender#yourdomain.com>',
#reply_to='sender#yourdomain.com'
Before use, Database Mail must be enabled using the Database Mail Configuration Wizard, or sp_configure. A database or Exchange admin might need to help you configure this.
See
http://msdn.microsoft.com/en-us/library/ms190307.aspx
and
http://www.codeproject.com/Articles/485124/Configuring-Database-Mail-in-SQL-Server for more information.
You can do it with a cursor also.
Assuming that you have created an Account and a Profile e.g. "profile" and an Account and you have the table that holds the emails ready e.g. "EmailMessageTable" you can do the following:
USE database_name
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE mass_email AS
declare #email nvarchar (50)
declare #body nvarchar (255)
declare test_cur cursor for
SELECT email from [dbo].[EmailMessageTable]
open test_cur
fetch next from test_cur into
#email
while ##fetch_status = 0
begin
set #body = (SELECT body from [dbo].[EmailMessageTable] where email = #email)
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'profile',
#recipients = #email,
#body = #body,
#subject = 'Credentials for Web';
fetch next from test_cur into
#email
end
close test_cur
deallocate test_cur
After that all you have to do is execute the Stored Procedure
EXECUTE mass_email
GO
Here's an example of how you might concatenate email addresses from a table into a single #recipients parameter:
CREATE TABLE #emailAddresses (email VARCHAR(25))
INSERT #emailAddresses (email) VALUES ('foo#foobar.com')
INSERT #emailAddresses (email) VALUES ('bar#foobar.com')
INSERT #emailAddresses (email) VALUES ('buzzlightyear#foobar.com')
DECLARE #recipients VARCHAR(MAX)
SELECT #recipients = COALESCE(#recipients + ';', '') + email
FROM #emailAddresses
SELECT #recipients
DROP TABLE #emailAddresses
The resulting #recipients will be:
foo#foobar.com;bar#foobar.com;buzzlightyear#foobar.com
In-order to make SQL server send email notification you need to create mail profile from Management, database mail.
1) User Right click to get the mail profile menu and choose configure database mail
2)choose the first open (set up a database mail by following the following tasks) and press next
Note: if the SMTP is not configured please refer the the URL below
http://www.symantec.com/business/support/index?page=content&id=TECH86263
3) in the second screen fill the the profile name and add SMTP account, then press next
4) choose the type of mail account ( public or private ) then press next
5) change the parameters that related to the sending mail options, and press next
6) press finish
Now to make SQL server send an email if action X happened you can do that via trigger or job ( This is the common ways not the only ones).
1) you can create Job from SQL server agent, then right click on operators and check mails (fill the your email for example) and press OK after that right click Jobs and choose new job
and fill the required info as well as the from steps, name, ...etc and from notification tab select the profile you made.
2) from triggers please refer to the example below.
AS
declare #results varchar(max)
declare #subjectText varchar(max)
declare #databaseName VARCHAR(255)
SET #subjectText = 'your subject'
SET #results = 'your results'
-- write the Trigger JOB
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'SQLAlerts',
#recipients = 'xxxx#xxxx.com',
#body = #results,
#subject = #subjectText,
#exclude_query_output = 1 --Suppress 'Mail Queued' message
GO
sometimes while not found sp_send_dbmail directly. You may use 'msdb.dbo.sp_send_dbmail' to try
(Work fine on Windows Server 2008 R2 and is tested)
To send mail through SQL Server we need to set up DB mail profile we can either use T-SQl or SQL Database mail option in sql server to create profile. After below code is used to send mail through query or stored procedure.
Use below link to create DB mail profile
http://www.freshcodehub.com/Article/42/configure-database-mail-in-sql-server-database
http://www.freshcodehub.com/Article/43/create-a-database-mail-configuration-using-t-sql-script
--Sending Test Mail
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'TestProfile',
#recipients = 'To Email Here',
#copy_recipients ='CC Email Here', --For CC Email if exists
#blind_copy_recipients= 'BCC Email Here', --For BCC Email if exists
#subject = 'Mail Subject Here',
#body = 'Mail Body Here',
#body_format='HTML',
#importance ='HIGH',
#file_attachments='C:\Test.pdf'; --For Attachments if exists

How to email query output

I have a basic query, and i'd like to email the results. How can I do this at the query level? So if my query is:
SELECT
Store_Id, Paid_Out_Amount, Paid_Out_Comment,
Paid_Out_Datetime, Update_UserName
FROM Paid_Out_Tb
WHERE (Store_Id = 1929) OR
(Paid_Out_Amount > 50) AND
(Paid_Out_Datetime BETWEEN
CONVERT(DATETIME, '2012-06-01 00:00:00', 102) AND
CONVERT(DATETIME, '2012-06-30 00:00:00', 102))
How would I email the output? I have a procedure to send email via SMTP and the parameters are #From, #To, #Subject and #body... which works.. How would I make the body the outcome of the query?
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [dbo].[sp_SQLNotify]
#From varchar(100) ,
#To varchar(100) ,
#Subject varchar(100)=" ",
#Body varchar(4000) = "Test"
/*********************************************************************
This stored procedure takes the above parameters and sends an e-mail.
All of the mail configurations are hard-coded in the stored procedure.
Comments are added to the stored procedure where necessary.
Reference to the CDOSYS objects are at the following MSDN Web site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_messaging.asp
***********************************************************************/
AS
Declare #iMsg int
Declare #hr int
Declare #source varchar(255)
Declare #description varchar(500)
Declare #output varchar(1000)
--************* Create the CDO.Message Object ************************
EXEC #hr = sp_OACreate 'CDO.Message', #iMsg OUT
--***************Configuring the Message Object ******************
-- This is to configure a remote SMTP server.
-- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
EXEC #hr = sp_OASetProperty #iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendusing").Value','2'
-- This is to configure the Server Name or IP address.
-- Replace MailServerName by the name or IP of your SMTP Server.
EXEC #hr = sp_OASetProperty #iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value', '10.1.1.10'
-- Save the configurations to the message object.
EXEC #hr = sp_OAMethod #iMsg, 'Configuration.Fields.Update', null
-- Set the e-mail parameters.
EXEC #hr = sp_OASetProperty #iMsg, 'To', #To
EXEC #hr = sp_OASetProperty #iMsg, 'From', #From
EXEC #hr = sp_OASetProperty #iMsg, 'Subject', #Subject
-- If you are using HTML e-mail, use 'HTMLBody' instead of 'TextBody'.
EXEC #hr = sp_OASetProperty #iMsg, 'TextBody', #Body
EXEC #hr = sp_OAMethod #iMsg, 'Send', NULL
-- Sample error handling.
IF #hr <>0
select #hr
BEGIN
EXEC #hr = sp_OAGetErrorInfo NULL, #source OUT, #description OUT
IF #hr = 0
BEGIN
SELECT #output = ' Source: ' + #source
PRINT #output
SELECT #output = ' Description: ' + #description
PRINT #output
END
ELSE
BEGIN
PRINT ' sp_OAGetErrorInfo failed.'
RETURN
END
END
-- Clean up the objects created.
EXEC #hr = sp_OADestroy #iMsg
PRINT 'Mail Sent!'
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
This is the procedure i'm using to send the mail... which works... I just want to add a spot in it to send the results of the query above it... Can this be done easily within in the procedure?
Use the SQL Server Powershell pack. An example (with detailed explanation) of using it to obtain output is here.
(The above is taken from this SO answer, but to clarify something s/he says: SQL Server 2008 client components is required (Express should be fine), but it can work with SQL Server 2000 databases (source).)
You can also use a variable for a direct loop concatenation. See https://stackoverflow.com/a/4447564/1180926 (although you would use tab and newline delimiters instead of HTML code).
You would then just change your query accordingly, store it in #Body, and you're done!