If the mail is sent by SQL Server and successfully received in your client software’s inbox, you can proceed to the next section to learn how to use the sp_send_dbmail stored proce-dure
Trang 1If the test fails, click Troubleshoot, and SMSS opens the “Troubleshooting Database Mail”
Books Online topic, which provides a solid set of troubleshooting steps to get you started
If the mail is sent by SQL Server and successfully received in your client software’s inbox,
you can proceed to the next section to learn how to use the sp_send_dbmail stored
proce-dure to send email from T-SQL Otherwise, look for more troubleshooting help in the
“Related Views and Procedures” section of this chapter
Sending and Receiving with Database Mail
If you’re building client applications that rely heavily on Database Mail, it’s crucial to gain
an in-depth understanding of its underlying architecture The following sections provide
detailed information on its inner workings
The Service Broker Architecture
As noted earlier, SQL Server relies on Service Broker (SSB) to activate the Database Mail
process (DatabaseMail.exe) used to send mail DatabaseMail.exe uses ADO.NET to
connect to SQL Server and to read from and write to SSB queues (found in msdb) that hold
send requests and send statuses in the form of typed SSB messages You can view these
queues (InternalMailQueue and ExternalMailQueue) in the Object Browser by selecting
Service Broker and then the Queues folder If you look a bit further in the Object
Browser, you see how the mail transmission architecture is implemented (in part) as an
SSB application, as you find the corresponding internal and external Database Mail SSB
services (InternalMailService and ExternalMailService), SSB message types (SendMail
and SendMailStatus), and a single SSB contract (SendMail/v1.0)
SSB’s involvement with Database Mail works like this:
1 sp_send_dbmail (as the SSB initiator) is invoked and returns immediately Under the
covers, this adds an SSB message of type SendMail to the SSB mail queue, activating
the undocumented internal stored procedure sp_ExternalMailQueueListener Note
that the mail message itself is saved to one or more of the msdb tables (such as
sysmail_unsentitems and sysmail_attachments) if there are any attachments
2 SSB launches DatabaseMail.exe (running under the credentials of the SQL Server
service), which, in turn, connects back to SQL Server, using Windows
Authentication
3 DatabaseMail.exe reads the queued SSB send message, retrieves the mail message
data, sends the email, and, finally (acting as the SSB target), places a message of
type SendMailStatus in the mail status queue, reporting on the mail sending
success or failure
4 When there’s nothing left to be sent in the outbound queue, and the maximum
process idle time has been reached, DatabaseMail.exe exits
Trang 2Sending Email
The SSB queues that Database Mail uses must first be enabled before you can send mail
from a session You do this by executing the msdb stored procedure sysmail_start_sp
This procedure is similar to its predecessor, xp_startmail (as it must be called before
sending), except that it has no parameters and, of course, has nothing to do with MAPI It
returns 0 or 1, indicating success or failure If you don’t call this procedure, you receive
this error message:
Mail not queued Database Mail is stopped Use sysmail_start_sp to
start Database Mail
To temporarily disable SSB’s activation of the mail process, you execute sysmail_stop_sp
(also with no parameters), which returns 0 or 1 If you send mail from code after this
disabling this process, these messages will be queued The external process is not started
until sysmail_start_sp is called again To check on the status of Database Mail, you can
execute sysmail_help_status_sp (with no parameters) To check on the status of the
queues, you execute sysmail_help_queues_sp
After you execute sysmail_start_sp, you’re ready to begin sending mail using the
sp_send_dbmail stored procedure It has 21 parameters, most of which are optional As the
query engine will tell you if you try to execute it with no or too few parameters, at least
one of the following parameters must be specified: @body, @query, @file_attachments, or
@subject You also must specify one of the following: @recipients, @copy_recipients, or
@blind_copy_recipients
NOTE
For the following T-SQL examples to work, you must first configure a default profile
using either the Database Mail Configuration Wizard or Database Mail stored
proce-dures, as detailed earlier
A minimally parameterized test call might look like the following:
exec msdb.dbo.sp_send_dbmail @body=’Testing ’, @subject=’A Test’,
@recipients=’test@samspublishing.com’
go
Mail Queued
Table 15.2 describes the parameters, their types, and the xp_sendmail parameters to which
Trang 3TABLE 15.2 Parameters for Database Mail Stored Procedure sp_send_dbmail
Parameter to Which It Corresponds
@profile_name The sysname of the profile whose
SMTP accounts will be used to send
Not available in xp_sendmail
@recipients A varchar(max)
semicolon-delim-ited list of the recipients’ email addresses
Same as xp_sendmail
@copy_recipients A varchar(max)
semicolon-delim-ited list of the carbon copy recipi-ents’ email addresses
Same as xp_sendmail
@blind_copy_recipients A varchar(max)
semicolon-delim-ited list of the blind carbon copy recipients’ email addresses
Same as xp_sendmail
@subject The nvarchar(255) email subject Same as xp_sendmail
@body The nvarchar(max) email body Was @message in
xp_sendmail
@body_format One of the two varchar (20)
email format type strings, either
’HTML’ or ’TEXT’ (the default)
Not available in xp_sendmail
@importance One of the three varchar (6)
email importance strings, either
’Low’, ’Normal’ (the default), or
’High’
Not available in xp_sendmail
@sensitivity One of the four varchar (12)
email sensitivity strings, either
’Normal’ (the default),
’Personal’, ’Private’, or
’Confidential’
Not available in xp_sendmail
@file_attachments An nvarchar(max)
semicolon-delimited list of absolute paths to files to attach
Was @attachments in xp_sendmail
Trang 4@query An nvarchar(max) T-SQL code
string to be executed when the message is sent The code is executed in a different session than the calling session, so vari-able scope is a consideration
Same as xp_sendmail
@execute_query_database The sysname of the database in
which the T-SQL in query is to be executed
Was @dbuse in xp_sendmail
@attach_query_result_as_file A bit value indicating whether the
results of the T-SQL in query should be an attachment (1) or appended to the body (0; the default)
Was @attach_results
in xp_sendmail
@query_attachment_filename The nvarchar(255) filename for
the attached query results (as per
@query and
@attach_query_result_as_file)
If not specified, the generated file-name is arbitrary (usually QueryResults [some number].txt)
In xp_sendmail, the first filename in
@attachments was used
@query_result_header A bit value indicating whether the
query result (1; the default) should include the column headers
Was @no_header in xp_sendmail
@query_result_width An int value (defaulting to 256;
you specify a number between 10 and 32767) indicating how wide a line in the query results should be before line wrapping occurs
Was @width in xp_sendmail
@query_result_separator A char(1) value (defaulting to a
space) that indicates the query results column separator
Was @separator in xp_sendmail
Trang 5TABLE 15.2 Parameters for Database Mail Stored Procedure sp_send_dbmail
Parameter to Which It Corresponds
@exclude_query_output A bit value that indicates whether
to suppress the query output (such
as rowcounts, print statements, and so forth) from being printed on the query console 0 (do not suppress) is the default
Was @no_output in xp_sendmail
@append_query_error A bit value that indicates whether
to send the email if the query to
be executed raises an error If set
to 1, the error message is appended to the query output, and the query window for the session also displays the error (“A severe error occurred on the current command The results, if any, should be discarded.”) If set to 0 (the default), the message is not sent, and sp_send_dbmail returns
1
Not available in xp_sendmail, but similar to @echo_error
@query_no_truncate A bit value that indicates whether
to truncate query results having long values (such as
varchar(max), text, xml, and so on) greater than 256 It defaults to
0 (off) Microsoft warns that using this can slow things down, but it is the only way to properly send these types
Not available in xp_sendmail
@mailitem_id An output parameter, an int value
indicating the unique mailitem_id
of the message You see this as a column in the views discussed in the section “Related Views and Procedures,” later in this chapter
Not available in xp_sendmail
Note that the @type and @set_user parameters for xp_sendmail are not available @type, of
course, is obsolete because it is MAPI specific @set_user is also obsolete because the
content of the T-SQL to be executed may contain an EXECUTE AS statement
Trang 6is used (as in these examples) If there is no default public profile, an error is raised
The example shown in Listing 15.1 sends an email containing an xml result to a recipient
as an attached Extensible Application Markup Language (XAML) document, retrieved from
the AdventureWorks2008.Production.Illustration column
LISTING 15.1 Sending XML as an Attachment with Database Mail
USE AdventureWorks2008
GO
DECLARE
@subject nvarchar(255),
@body varchar(max),
@query nvarchar(max),
@IllustrationId int,
@query_attachment_filename nvarchar(255),
@mailitem_id int
SELECT
@IllustrationId = pi.IllustrationId,
@subject = ‘XAML for “‘ + pm.Name + ‘“ attached ‘
FROM Production.Illustration pi
JOIN Production.ProductModelIllustration pmi
ON pmi.IllustrationId = pi.IllustrationId
JOIN Production.ProductModel pm
ON pm.ProductModelID = pmi.ProductModelID
SELECT
@body =
N’Attached, please find the XAML diagram for illustration #’ +
CAST(@IllustrationId as nvarchar(10)) +
‘ A XAML browser plug-in is required to view this file.’
SELECT @query =
N’SELECT Diagram FROM Production.Illustration
WHERE IllustrationId = ‘ + CAST(@IllustrationId as nvarchar(10))
SELECT @query_attachment_filename = N’PM_’ +
CAST(@IllustrationId as nvarchar(10)) + ‘.xaml’
Trang 7exec msdb.dbo.sp_send_dbmail
@subject=@subject,
@body=@body,
@recipients=’test@samspublishing.com’,
@query=@query,
@execute_query_database=’AdventureWorks2008’,
@attach_query_result_as_file=1,
@query_attachment_filename=@query_attachment_filename,
@query_no_truncate=1,
@exclude_query_output=1,
@query_result_width=32767,
@mailitem_id=@mailitem_id OUTPUT
SELECT sent_status, sent_date
FROM msdb.dbo.sysmail_allitems
WHERE mailitem_id = @mailitem_id
GO
sent_status sent_date
—
————-unsent NULL
(1 row(s) affected)
Note that you must set @query_no_truncate to 1 and @query_result_width to the
maximum (to be safe) value for the attached query results to contain consistently
well-formed XML In addition, you should not include any carriage returns or line feeds in the
body of the message, or the SMTP servers may not be able to send it
The example in Listing 15.2 sends some query results as a comma-separated value (CSV)
file that can be imported into programs such as Microsoft Excel (You need to use the Get
External Data command to accomplish this with Excel 9.)
LISTING 15.2 Sending CSV Data as an Attachment with Database Mail
USE AdventureWorks2008
GO
DECLARE @mailitem_id int, @tab char(1)
SET @tab = char(13)
exec msdb.dbo.sp_send_dbmail
@subject=’D Margheim, Contact Info’,
@body=’Attached is Diane Margheim’’s contact info, in CSV format.’,
@recipients=’test@samspublishing.com’,
@query=N’SELECT BusinessEntityID, Title, FirstName, MiddleName, LastName
FROM Person.Person
WHERE BusinessEntityId = 8’,
@execute_query_database=’AdventureWorks2008’,
Trang 8@mailitem_id=@mailitem_id OUTPUT
SELECT sent_status, sent_date
FROM msdb.dbo.sysmail_allitems
WHERE mailitem_id = @mailitem_id
GO
sent_status sent_date
—
————-unsent NULL
(1 row(s) affected)
Notice that in both of these code listings, the values selected from the sent_status and
sent_date columns of sysmail_allitems indicate that the mail has not yet been sent The
reason is that mail sending (like all other SSB messaging) is asynchronous: The message is
immediately queued, and the Mail process later picks it up and sends it To find out more
about system views such as sysmail_allitems, see the section “Related Views and
Procedures,” later in this chapter
Receiving Email
The only way for SQL Server 2008 to receive email is by using the legacy stored
proce-dures, such as sp_processmail, with SQL Mail Database Mail does not support receiving
incoming messages because there is no IMAP or POP3 support This may have something
to do with the fact that receiving email can represent a major security risk Imagine what
a denial-of-service attack on a database cluster could do to an organization Or consider
the danger of an incoming email request resulting in the execution of a query such as
DROP DATABASE X Most SQL Server data is too precious to jeopardize in this manner
Microsoft has also made it clear that SQL Mail will be phased out in the next release of
SQL Server Plus, there are many better alternatives to using this methodology, such as
using native Web services (as discussed in Chapter 48, “SQL Server Web Services”), using
.NET CLR-integrated assembly code (as discussed in Chapter 45, “SQL Server and the NET
Framework”), or building a dedicated Service Broker application (as discussed in Chapter
49)
Using SQL Server Agent Mail
As with SQL Server 2000, SQL Server 2008’s Agent has the capability to send email
notifi-cations They may be triggered by alerts or scheduled task completions, such as jobs SQL
Server 2008 provides the option of using either SQL Mail or Database Mail to do the
sending, but SQL Mail will soon be phased out, and Database Mail is by far the more
robust choice As with Database Mail, SQL Server Agent Mail is turned off by default, and
Trang 9Job Mail Notifications
The following sections show an example in which you create a SQL Server Agent Mail
operator that SQL Server Agent will notify when a job completes
Creating an Operator
First, you need to create an operator To do so, using the Object Browser, you expand the
SQL Server Agent node and then right-click the Operators folder and select New
Operator Then you should name this new operator Test Database Mail Operator and
provide an email address for testing purposes in the Email Name text box You can use
any valid email address you can access with your email client software You click OK to
save the new operator
Enabling SQL Agent Mail
Next, you need to enable SQL Server Agent to use Database Mail You right-click the SQL
Server Agent node and then select Properties On the left side of the Properties dialog
that appears (see Figure 15.2), you click the Alert System link Under the Mail Session
group, you check the Enable Mail Profile check box In the Mail System drop-down list,
you select Database Mail (this is also the place where you can choose SQL Mail, if you
desire) In the Mail Profile drop-down list, you select the default SQL 2008 profile you
created earlier and then click OK By doing this, you are telling SQL Server Agent to use
the SMTP servers in your default profile to send email You need to restart SQL Server
Agent by using the right-click menu
FIGURE 15.2 Using the SQL Server Agent Properties dialog to configure Database Mail
Trang 10click the Steps link on the left side of the dialog Next, you click the New button and add
a step named Test Mail Step 1 You should leave the type as Transact-SQL and then
change the database selection to AdventureWorks2008 In the Command text box, you
enter the following code:
RAISERROR(‘This is simply a test job.’, 10, 1)
Next, you click the Advanced link on the left side of the dialog, and in the On Success
Action drop-down list, you select Quit the Job Reporting Success Then you click the
Notifications link on the left side of the dialog Next, under Actions to Perform When the
Job Completes, you check the Email check box and select the operator you just created
From the drop-down to the right, you select When the Job Completes and then click OK to
save the job
Testing the Job-Completion Notification
To test the email configuration and notification you just set up, you right-click the job
name under the Jobs folder and then select Start Job If everything is set up properly, an
email message appears in your inbox, indicating the job’s successful completion Its body
text might look something like this:
JOB RUN: ‘Database Mail Test Job’ was run on 5/7/2009 at 8:37:22 PM
DURATION: 0 hours, 0 minutes, 0 seconds
STATUS: Succeeded
MESSAGES: The job succeeded The Job was invoked by User [TestUser]
The last step to run was step 1 (Test Mail Step 1)
Alert Mail Notifications
As another example, in the following sections, you’ll create a simple user-defined alert
that you can trigger directly from T-SQL script
Creating an Alert
You start by creating an alert To do this, you use the Object Browser to expand the SQL
Server Agent node; then you right-click the Alerts node and select New Alert In the
Alert Properties dialog that appears (see Figure 15.3), you name the new alert Database
Mail Test Alert and make sure the Enabled check box is checked For the Event type,
you leave the selection on SQL Server Event Alert Under Event Alert Definition, select
AdventureWorks2008 from the Database Name drop-down list, and then click the Severity
option button and choose 010 - Information Next, check the Raise Alert When Message