How to send email from SQL Server? - sql

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

Related

How to create a trigger to send email when a new record is added in to the table

When I run an interface with name 'personimport' it will generate a new record in the table (run history).
There are 5 columns in the table:
interface-id, interface name, date, personid, error msg
Inserting "1, qwerty, 2019-09-11, a1" is successful, but inserting "2, person import, 2019-09-12, a2" throws an error .
Whenever a new record is added into this table with the name 'person import' I want to send an email to set of employees.
How to write a trigger for this in SQL Server?
You need to have database mail configured:
https://learn.microsoft.com/en-us/sql/relational-databases/database-mail/configure-database-mail?view=sql-server-2017
You need to create a trigger:
From SSMS goto the table and expand
Right click triggers, and "New Trigger"
Name your trigger, on table name, and after insert
CREATE TRIGGER SendTheEmails
ON runhistory
AFTER insert
AS
BEGIN
-- Insert statements for trigger here
END
GO
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017
Then for the SQL to email:
Declare #message varchar(max)
Declare #subjectline varchar(60)
set #subjectline = 'Your Subject'
set #message = 'Your Message body'
EXEC msdb.dbo.sp_send_dbmail #profile_name = 'dbmailProfileName'
, #recipients = 'youremails#yourdomain'
, #subject = #subjectline
, #body_format = 'html'
, #body = #message
Obviously you can declare other variables, and use the insert table for further information.
Yeah, and as Fillburt said, this seems like a duplicate of Send e-mail from a trigger

Why am I getting the following error when using database mail -> Procedure sysmail_verify_profile_sp, profile name is not valid?

I wrote a trigger to grab a certain row of records after a specific column change and store the records into another table called Feedback.
Then I am trying to using the following code to email the changes to our users using sp_send_dbmail.
However, when testing the code, I keep getting the following error messages:
Msg 14607, Level 16, State 1, Procedure sysmail_verify_profile_sp, Line 42
profile name is not valid
The profile is called Feedback Survey and it is set up correctly using Database Mail Configuration wizard.
What could I be doing wrong?
Declare #email nvarchar(MAX),#content1 nvarchar(4000), #RequestID INT, #custname nvarchar(200)
select #email = '', #content1 = '', #RequestID = 0, #custname = ''
SET #content1 = 'SET QUOTED_IDENTIFIER OFF;
This is a computer generated email message.
Please DO NOT use the REPLY button above to respond to this email.
Dear '+ #custname +':
Thank you for using the order processing system.
Please click the link below to complete a survey
http://satisfactionsurvey.php?wo=#RequestID
Regards,
Order administrator. '
SELECT top 1 #email = #email+';'+Email, #content1 = #content1
FROM Feedback
WHERE Status = 'Completed'
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Feedback Survey', -- our defined email profile or static info
#recipients = #email, -- Authorized user email
#blind_copy_recipients = 'jab.judah#yahoo.com',
#subject = 'Feedback Survey',
#body = #content1;
--delete records after sending email.
Delete FROM Feedback
In the Database Mail Configuration Wizard, go to Manage Profile Security and check the settings for public and private profiles.
Check if the Login that you use is connected to the profile 'Feedback Survey'.
More detailed information can be found in Msg 14607, Level 16, State 1 – profile name is not valid (Internet Archive link from 2014-01-15).

Agent job that emails from custom email table

I used to have triggers in my database that used cursors / sp_send_dbmail to email when certain columns were updated. I was told this was not best practice so I created a new table called EmailNotify that contains columns like recepient, subject, body etc. So instead the triggers now insert into this table the email I want to send.
I want to create a Job that runs every few minutes that checks this table and emails. The item below is what I came up with but is it okay to use cursors in this case? Should the table include a sent field so I know which rows I sent? Can I change that inside the cursor? Or would it be recommended to truncate the table afterwards?
DECLARE #emailSubject AS NVARCHAR(100);
DECLARE #emailRecipients AS NVARCHAR(100);
DECLARE #emailBody AS NVARCHAR(max);
DECLARE cur CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT
recipients,
subject,
body
FROM
EmailNotify;
OPEN cur
FETCH NEXT FROM cur INTO
#emailRecipients,
#emailSubject,
#emailBody
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'name',
#recipients = #emailRecipients,
#body = #emailBody,
#body_format = 'HTML',
#subject = #emailSubject;
FETCH NEXT FROM cur INTO
#emailRecipients,
#emailSubject,
#emailBody
END
CLOSE cur
DEALLOCATE cur
I would
Add an EmailSent(DATETIME) = NULL column to your table
Create an EmailSent variable at the top of your proc and set it to GETDATE()
UPDATE <YOURTABLE> SET EmailSent = #EmailSent WHERE EmailSent IS NULL
Add a WHERE EmailSent = #EmailSent to your query for the email
You can accomplish this with a SSRS report with a subscription or data-bound subscription instead of this job, but it's really just a matter of preference. Formatting is easier in SSRS, otherwise you're messing with dynamic HTML in your message body. Been there, not pleasant.

How do I modify stored procedure so it can process request based on request mode?

We wrote a stored procedure that uses SQL Server's send_dbmail feature to send emails to potential users with details of their registrations.
This stored procedure works great.
The only issue we currently have is that users will also like to request a copy of their forgotten password.
I can write another stored procedure to handle this? However, is there a way to modify the stored procedure below so that it recognizes the mode of the request?
For instance, currently a user creates an account and details of the account are stored in tblLogin table.
This stored procedure grabs the account info, stores it in Notifications table and finally email details of this account to the user who just registered.
Similarly, we would like the same stored procedure to process when a user uses the Forgotten Password feature to request a password.
How do I modify the stored procedure send email based on what is being requested?
In other words, if the data stored in tblLogin table is for a new account creation, the stored procedure should grab it and send an email to user with details.
If data is for forgotten password, the stored procedure should only email that info as well.
Is this possible with the stored procedure below?
ALTER PROCEDURE [dbo].[GetRegistrationInfo]
AS
BEGIN
DECLARE Register_Cursor CURSOR FOR
SELECT
LoginId, FullName, email, Password
FROM
[tblLogin]
WHERE
ProcessedFlag = 'No'
ORDER BY
LoginId DESC
OPEN Register_Cursor
DECLARE #LoginId INT
DECLARE #fullname NVARCHAR(100)
DECLARE #email NVARCHAR(MAX)
DECLARE #password NVARCHAR(20)
-- Get the current MAX ID
DECLARE #mailID as INT
-- Start reading each record from the cursor.
FETCH Register_Cursor INTO #LoginId, #fullname, #email, #password
WHILE ##FETCH_STATUS = 0
BEGIN
--set #mailID = (SELECT max(mailID) from Notifications) Not needed; let's auto-genereate the id
INSERT INTO [Notifications] (mailContent, LoginId, FullName, email, Password, sender, Sent)
VALUES ('This is a computer generated email message.
Please DO NOT use the REPLY button above to respond to this email.
Dear '+#FullName+':
Thanks for registering to take the Training!
Below are details of your registration information:
Your UserName is: '+#email+'.
Your Password is: '+#password+'.
Once you have retrieved your login information, please click the link below to get back to Training login screen and begin to begin to enjoy the benefits of membership.
http://servername/training/
Regards,
The Registrations & Elections Office.', #LoginId, #FullName, #email, #Password, 'NoReply#serverdomain', 'No')
FETCH Register_Cursor INTO #LoginId, #FullName, #email, #password
END
CLOSE Register_Cursor
DEALLOCATE Register_Cursor
END
BEGIN
DECLARE MAIL_CURSOR CURSOR FOR
SELECT mailid, sender, mailcontent
FROM [Notifications]
WHERE Sent = 'No'
DECLARE #mail1 INT
DECLARE #sender NVARCHAR(100)
DECLARE #content1 NVARCHAR(4000)
OPEN MAIL_CURSOR
FETCH MAIL_CURSOR INTO #mail1, #sender, #content1
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #email = #email + ';' + Email
FROM [Notifications]
WHERE sent = 'No'
-- exec sp_send_cdontsmail #mail1, null,null,#content1,null
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'The Office',
#recipients = #email, -- your email
--#blind_copy_recipients = #email,
#subject = 'Your Account Details',
#body = #content1;
-- Update the record in Notifications table where Sent = 'No'.
UPDATE [Notifications]
SET Sent = 'Yes'
WHERE Sent = 'No' AND mailid = #mail1
UPDATE [tblLogin]
SET ProcessedFlag = 'Yes'
WHERE ProcessedFlag = 'No' AND LoginId = #LoginId
FETCH MAIL_CURSOR INTO #mail1, #sender, #content1
END
CLOSE MAIL_CURSOR
DEALLOCATE MAIL_CURSOR
END
Sorry if I’m missing something here but this looks like you only need one IF - ELSE statement that will send one message in one case and another message otherwise…

Send Email From Database

Im trying to send an email from a sever to a couple of recipients.
I do query my database using:
SELECT Email from payrollchecksystem
And than use the following to send the email
USE msdb
GO
EXEC sp_send_dbmail #profile_name='SQL Server Alerts System',
#recipients = I DONT KNOW WHAT TO PUT HERE
#subject='Test message',
#body='This is the body of the test message.
Congrates Database Mail Received By you Successfully.'
My problem is that I dont know what to put for #recipients when trying to send all the emails I got from the payrollchecksystem table?
To separate your e-mails into a semi-colon delimited string, use COALESCE:
DECLARE #EmailList varchar(MAX)
SELECT #EmailList = COALESCE(#EmailList + ';', '') + Email
FROM payrollchecksystem
WHERE Email IS NOT NULL
SELECT #EmailList
Then you can use #EmailList like so:
USE msdb
GO
EXEC sp_send_dbmail #profile_name='SQL Server Alerts System',
#recipients = #EmailList,
#subject='Test message',
#body='This is the body of the test message. Congrates Database Mail Received By you Successfully.'
http://msdn.microsoft.com/en-us/library/ms190307.aspx
#recipients
Is a semicolon-delimited list of
e-mail addresses to send the message
to