

# 在 Amazon RDS for SQL Server 上使用数据库邮件
<a name="SQLServer.DBMail"></a>

您可以使用数据库邮件从 Amazon RDS on SQL Server 数据库实例向用户发送电子邮件。这些消息可以包含文件和查询结果。数据库邮件包括以下组件：
+ **配置和安全对象** – 这些对象可以创建配置文件和账户，并存储在 `msdb` 数据库中。
+ **消息收发对象** – 这些对象包括用于发送消息的 [sp\$1send\$1dbmail](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-send-dbmail-transact-sql) 存储过程以及保存有关消息信息的数据结构。相关内容均存储在 `msdb` 数据库中。
+ **日志记录和审计对象** – 数据库邮件将日志记录信息写入 `msdb` 数据库和 Microsoft Windows 应用程序事件日志中。
+ **数据库邮件可执行文件** – `DatabaseMail.exe` 读取 `msdb` 数据库中的队列并发送电子邮件。

RDS 在 Web 版、标准版和企业版上支持所有 SQL Server 版本的数据库邮件。

## 限制
<a name="SQLServer.DBMail.Limitations"></a>

以下限制适用于在 SQL Server 数据库实例上使用数据库邮件：
+ SQL Server 精简版不支持数据库邮件。
+ 不支持修改数据库邮件配置参数。如欲查看预设（默认）值，请使用 [sysmail\$1help\$1configure\$1sp](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-help-configure-sp-transact-sql) 存储过程。
+ 不完全支持文件附件。有关更多信息，请参阅“[使用文件附件](#SQLServer.DBMail.Files)”。
+ 文件附件的最大大小为 1 MB。
+ 数据库邮件需要对多可用区数据库实例进行额外配置 有关更多信息，请参阅“[多可用区部署的注意事项](#SQLServer.DBMail.MAZ)”。
+ 不支持将 SQL Server Agent 配置为向预定义运算符发送电子邮件。

# 启用数据库邮件
<a name="SQLServer.DBMail.Enable"></a>

使用以下过程为数据库实例启用数据库邮件：

1. 创建新的参数组。

1. 修改参数组以将 `database mail xps` 参数设置为 1。

1. 将参数组与数据库实例相关联。

## 为数据库邮件创建参数组
<a name="DBMail.CreateParamGroup"></a>

为与 SQL Server 版本和数据库实例版本对应的 `database mail xps` 参数创建参数组。

**注意**  
您也可以修改现有参数组。按照[修改启用数据库邮件的参数](#DBMail.ModifyParamGroup)中过程操作。

### 控制台
<a name="DBMail.CreateParamGroup.Console"></a>

以下示例为 SQL Server 标准版 2016 创建一个参数组。

**创建参数组**

1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台：[https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)。

1. 在导航窗格中，选择**参数组**。

1. 选择**创建参数组**。

1. 在**创建参数组**窗格中，执行以下操作：

   1. 对于**参数组系列**，选择 **sqlserver-se-13.0**。

   1. 对于**组名称**，输入参数组的标识符，如 **dbmail-sqlserver-se-13**。

   1. 对于**描述**，输入 **Database Mail XPs**。

1. 选择**创建**。

### CLI
<a name="DBMail.CreateParamGroup.CLI"></a>

以下示例为 SQL Server 标准版 2016 创建一个参数组。

**创建参数组**
+ 使用以下命令之一。  
**Example**  

  对于 Linux、macOS 或 Unix：

  ```
  aws rds create-db-parameter-group \
      --db-parameter-group-name dbmail-sqlserver-se-13 \
      --db-parameter-group-family "sqlserver-se-13.0" \
      --description "Database Mail XPs"
  ```

  对于：Windows

  ```
  aws rds create-db-parameter-group ^
      --db-parameter-group-name dbmail-sqlserver-se-13 ^
      --db-parameter-group-family "sqlserver-se-13.0" ^
      --description "Database Mail XPs"
  ```

## 修改启用数据库邮件的参数
<a name="DBMail.ModifyParamGroup"></a>

修改与 SQL Server 版本和数据库实例版本对应的参数组中的 `database mail xps` 参数。

要启用数据库邮件，请将 `database mail xps` 参数设置为 1。

### 控制台
<a name="DBMail.ModifyParamGroup.Console"></a>

以下示例修改您为 SQL Server 标准版 2016 创建的参数组。

**修改参数组**

1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台：[https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)。

1. 在导航窗格中，选择**参数组**。

1. 选择参数组，例如 **dbmail-sqlserver-se-13**。

1. 在**参数**下，从参数列表中筛选 **mail**。

1. 选择**数据库邮件 xps**。

1. 选择**编辑参数**。

1. 输入 **1**。

1. 选择**保存更改**。

### CLI
<a name="DBMail.ModifyParamGroup.CLI"></a>

以下示例修改您为 SQL Server 标准版 2016 创建的参数组。

**修改参数组**
+ 使用以下命令之一。  
**Example**  

  对于 Linux、macOS 或 Unix：

  ```
  aws rds modify-db-parameter-group \
      --db-parameter-group-name dbmail-sqlserver-se-13 \
      --parameters "ParameterName='database mail xps',ParameterValue=1,ApplyMethod=immediate"
  ```

  对于：Windows

  ```
  aws rds modify-db-parameter-group ^
      --db-parameter-group-name dbmail-sqlserver-se-13 ^
      --parameters "ParameterName='database mail xps',ParameterValue=1,ApplyMethod=immediate"
  ```

## 将参数组与数据库实例相关联
<a name="DBMail.AssocParamGroup"></a>

您可以使用 AWS 管理控制台 或 AWS CLI 将数据库邮件参数组与数据库实例相关联。

### 控制台
<a name="DBMail.AssocParamGroup.Console"></a>

您可以将数据库邮件参数组与新的或现有的数据库实例相关联。
+ 对于新的数据库实例，请在启动实例时将其关联。有关更多信息，请参阅“[创建 Amazon RDS 数据库实例](USER_CreateDBInstance.md)”。
+ 对于现有数据库实例，请通过修改实例将其关联。有关更多信息，请参阅 [修改 Amazon RDS 数据库实例](Overview.DBInstance.Modifying.md)。

### CLI
<a name="DBMail.AssocParamGroup.CLI"></a>

您可以将数据库邮件参数组与新的或现有的数据库实例相关联。

**如欲使用数据库邮件参数组创建数据库实例**
+ 指定在创建参数组时使用的相同数据库引擎类型和主要版本。  
**Example**  

  对于 Linux、macOS 或 Unix：

  ```
  aws rds create-db-instance \
      --db-instance-identifier mydbinstance \
      --db-instance-class db.m5.2xlarge \
      --engine sqlserver-se \
      --engine-version 13.00.5426.0.v1 \
      --allocated-storage 100 \
      --manage-master-user-password \
      --master-username admin \
      --storage-type gp2 \
      --license-model li
      --db-parameter-group-name dbmail-sqlserver-se-13
  ```

  对于：Windows

  ```
  aws rds create-db-instance ^
      --db-instance-identifier mydbinstance ^
      --db-instance-class db.m5.2xlarge ^
      --engine sqlserver-se ^
      --engine-version 13.00.5426.0.v1 ^
      --allocated-storage 100 ^
      --manage-master-user-password ^
      --master-username admin ^
      --storage-type gp2 ^
      --license-model li ^
      --db-parameter-group-name dbmail-sqlserver-se-13
  ```

**如欲修改数据库实例并关联数据库邮件参数组**
+ 使用以下命令之一。  
**Example**  

  对于 Linux、macOS 或 Unix：

  ```
  aws rds modify-db-instance \
      --db-instance-identifier mydbinstance \
      --db-parameter-group-name dbmail-sqlserver-se-13 \
      --apply-immediately
  ```

  对于：Windows

  ```
  aws rds modify-db-instance ^
      --db-instance-identifier mydbinstance ^
      --db-parameter-group-name dbmail-sqlserver-se-13 ^
      --apply-immediately
  ```

# 配置数据库邮件
<a name="SQLServer.DBMail.Configure"></a>

您可以执行以下任务来配置数据库邮件：

1. 创建数据库邮件配置文件。

1. 创建数据库邮件账户。

1. 将数据库邮件账户添加到数据库邮件配置文件中。

1. 将用户添加到数据库邮件配置文件中。

**注意**  
如欲配置数据库邮件，请确保您对 `execute` 数据库中的存储过程拥有 `msdb` 权限。

## 创建数据库邮件配置文件
<a name="SQLServer.DBMail.Configure.Profile"></a>

如欲创建数据库邮件配置文件，请使用 [sysmail\$1add\$1profile\$1sp](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-profile-sp-transact-sql) 存储过程。以下示例创建一个名为 `Notifications` 的配置文件。

**如欲创建配置文件**
+ 使用以下 SQL 语句。

  ```
  USE msdb
  GO
  
  EXECUTE msdb.dbo.sysmail_add_profile_sp  
      @profile_name         = 'Notifications',  
      @description          = 'Profile used for sending outgoing notifications using Amazon SES.';
  GO
  ```

## 创建数据库邮件账户
<a name="SQLServer.DBMail.Configure.Account"></a>

如欲创建数据库邮件账户，请使用 [sysmail\$1add\$1account\$1sp](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-account-sp-transact-sql) 存储过程。以下示例使用 Amazon Simple Email Service 在私有 VPC 中的 RDS for SQL Server 数据库实例上创建一个名为 `SES` 的账户。

使用 Amazon SES 需要以下参数：
+ `@email_address` – 经过 Amazon SES 验证的身份。有关更多信息，请参阅[在 Amazon SES 中验证身份](https://docs.aws.amazon.com/ses/latest/dg/verify-addresses-and-domains.html)。
+ `@mailserver_name` – Amazon SES SMTP 端点。有关更多信息，请参阅[连接到 Amazon SES SMTP 端点](https://docs.aws.amazon.com/ses/latest/dg/smtp-connect.html)。
+ `@username` – Amazon SES SMTP 用户名。有关更多信息，请参阅[获取 Amazon SES SMTP 凭证](https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html)。

  请勿使用AWS Identity and Access Management用户名。
+ `@password` – Amazon SES SMTP 密码。有关更多信息，请参阅[获取 Amazon SES SMTP 凭证](https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html)。

**如欲创建账户**
+ 使用以下 SQL 语句。

  ```
  USE msdb
  GO
  
  EXECUTE msdb.dbo.sysmail_add_account_sp
      @account_name        = 'SES',
      @description         = 'Mail account for sending outgoing notifications.',
      @email_address       = 'nobody@example.com',
      @display_name        = 'Automated Mailer',
      @mailserver_name     = 'vpce-0a1b2c3d4e5f-01234567.email-smtp.us-west-2.vpce.amazonaws.com',
      @port                = 587,
      @enable_ssl          = 1,
      @username            = 'Smtp_Username',
      @password            = 'Smtp_Password';
  GO
  ```
**注意**  
作为安全最佳实践，请指定除此处所示提示以外的凭证。

## 将数据库邮件账户添加到数据库邮件配置文件中
<a name="SQLServer.DBMail.Configure.AddAccount"></a>

如欲将数据库邮件账户添加到数据库邮件配置文件中，请使用 [sysmail\$1add\$1profileaccount\$1sp](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-profileaccount-sp-transact-sql) 存储过程。以下示例将 `SES` 账户添加到 `Notifications` 配置文件中。

**如欲将账户添加到配置文件中**
+ 使用以下 SQL 语句。

  ```
  USE msdb
  GO
  
  EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
      @profile_name        = 'Notifications',
      @account_name        = 'SES',
      @sequence_number     = 1;
  GO
  ```

## 将用户添加到数据库邮件配置文件中
<a name="SQLServer.DBMail.Configure.AddUser"></a>

如欲向 `msdb` 数据库委托人授予使用数据库邮件配置文件的权限，请使用 [sysmail\$1add\$1principalprofile\$1sp](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-principalprofile-sp-transact-sql) 存储过程。*委托人*指可以请求获取 SQL Server 资源的实体。数据库委托人必须映射到 SQL Server 身份验证用户、Windows 身份验证用户或 Windows 身份验证组。

以下示例授予对 `Notifications` 配置文件的公有访问权限。

**如欲将用户添加到配置文件**
+ 使用以下 SQL 语句。

  ```
  USE msdb
  GO
  
  EXECUTE msdb.dbo.sysmail_add_principalprofile_sp  
      @profile_name       = 'Notifications',  
      @principal_name     = 'public',  
      @is_default         = 1;
  GO
  ```

## 数据库邮件的 Amazon RDS 存储过程和函数
<a name="SQLServer.DBMail.StoredProc"></a>

Microsoft 提供[存储过程](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/database-mail-stored-procedures-transact-sql)用于使用数据库邮件，例如创建、列出、更新和删除帐户和配置文件。此外，RDS 还提供了数据库邮件的存储过程和函数，如下表所示。


| 过程/功能 | 描述 | 
| --- | --- | 
| rds\$1fn\$1sysmail\$1allitems | 显示已发送的消息，包括其他用户提交的消息。 | 
| rds\$1fn\$1sysmail\$1event\$1log | 显示事件，包括其他用户提交的消息事件。 | 
| rds\$1fn\$1sysmail\$1mailattachments | 显示附件，包括其他用户提交的消息附件。 | 
| rds\$1sysmail\$1control | 启动和停止邮件队列（DatabaseMail.exe 进程）。 | 
| rds\$1sysmail\$1delete\$1mailitems\$1sp | 从数据库邮件内部表中删除所有用户发送的电子邮件。 | 

# 使用数据库邮件发送电子邮件
<a name="SQLServer.DBMail.Send"></a>

您可以使用数据库邮件的 [sp\$1send\$1dbmail](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-send-dbmail-transact-sql) 存储过程发送电子邮件。

## 用法
<a name="SQLServer.DBMail.Send.Usage"></a>

```
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'profile_name',
@recipients = 'recipient1@example.com[; recipient2; ... recipientn]',
@subject = 'subject',
@body = 'message_body',
[@body_format = 'HTML'],
[@file_attachments = 'file_path1; file_path2; ... file_pathn'],
[@query = 'SQL_query'],
[@attach_query_result_as_file = 0|1]';
```

以下参数为必需参数：
+ `@profile_name` – 要从中发送消息的数据库邮件配置文件的名称。
+ `@recipients` – 要向其发送消息的电子邮件地址列表，用分号分隔。
+ `@subject` – 消息主题。
+ `@body` – 消息的正文。您也可以使用声明的变量作为主体。

以下参数为可选参数：
+ `@body_format` – 此参数与声明的变量一起使用，从而以 HTML 格式发送电子邮件。
+ `@file_attachments` – 以分号分隔的消息附件列表。文件路径必须是绝对路径。
+ `@query` – 要运行的 SQL 查询。查询结果可以作为文件附加，也可以包含在消息正文中。
+ `@attach_query_result_as_file` – 是否将查询结果附加为文件。设置为 0 表示“否”，设置为 1 表示“是”。默认值是 0。

## 示例
<a name="SQLServer.DBMail.Send.Examples"></a>

以下示例演示了如何发送电子邮件。

**Example 向单个收件人发送消息**  

```
USE msdb
GO

EXEC msdb.dbo.sp_send_dbmail
     @profile_name       = 'Notifications',
     @recipients         = 'nobody@example.com',
     @subject            = 'Automated DBMail message - 1',
     @body               = 'Database Mail configuration was successful.';
GO
```

**Example 向多个收件人发送消息**  

```
USE msdb
GO

EXEC msdb.dbo.sp_send_dbmail
     @profile_name       = 'Notifications',
     @recipients         = 'recipient1@example.com;recipient2@example.com',
     @subject            = 'Automated DBMail message - 2',
     @body               = 'This is a message.';
GO
```

**Example 将 SQL 查询结果作为文件附件发送**  

```
USE msdb
GO

EXEC msdb.dbo.sp_send_dbmail
     @profile_name       = 'Notifications',
     @recipients         = 'nobody@example.com',
     @subject            = 'Test SQL query',
     @body               = 'This is a SQL query test.',
     @query              = 'SELECT * FROM abc.dbo.test',
     @attach_query_result_as_file = 1;
GO
```

**Example 以 HTML 格式发送消息**  

```
USE msdb
GO

DECLARE @HTML_Body as NVARCHAR(500) = 'Hi, <h4> Heading </h4> </br> See the report. <b> Regards </b>';

EXEC msdb.dbo.sp_send_dbmail
     @profile_name       = 'Notifications',
     @recipients         = 'nobody@example.com',
     @subject            = 'Test HTML message',
     @body               = @HTML_Body,
     @body_format        = 'HTML';
GO
```

**Example 数据库中发生特定事件时，使用触发器发送消息**  

```
USE AdventureWorks2017
GO
IF OBJECT_ID ('Production.iProductNotification', 'TR') IS NOT NULL
DROP TRIGGER Purchasing.iProductNotification
GO

CREATE TRIGGER iProductNotification ON Production.Product
   FOR INSERT
   AS
   DECLARE @ProductInformation nvarchar(255);
   SELECT
   @ProductInformation = 'A new product, ' + Name + ', is now available for $' + CAST(StandardCost AS nvarchar(20)) + '!'
   FROM INSERTED i;

EXEC msdb.dbo.sp_send_dbmail
     @profile_name       = 'Notifications',
     @recipients         = 'nobody@example.com',
     @subject            = 'New product information',
     @body               = @ProductInformation;
GO
```

# 查看消息、日志和附件
<a name="SQLServer.DBMail.View"></a>

您可以使用 RDS 存储过程查看消息、事件日志和附件。

**如欲查看所有电子邮件**
+ 使用以下 SQL 查询。

  ```
  SELECT * FROM msdb.dbo.rds_fn_sysmail_allitems(); --WHERE sent_status='sent' or 'failed' or 'unsent'
  ```

**如欲查看所有电子邮件事件日志**
+ 使用以下 SQL 查询。

  ```
  SELECT * FROM msdb.dbo.rds_fn_sysmail_event_log();
  ```

**如欲查看所有电子邮件附件**
+ 使用以下 SQL 查询。

  ```
  SELECT * FROM msdb.dbo.rds_fn_sysmail_mailattachments();
  ```

# 删除消息
<a name="SQLServer.DBMail.Delete"></a>

您可以使用 `rds_sysmail_delete_mailitems_sp` 存储过程删除消息。

**注意**  
当 DBMail 历史数据大小达到 1 GB 时，RDS 会自动删除邮件表项目，且保留期至少为 24 小时。  
如果您希望延长邮件项目的保留时间，可以将其存档。有关详细信息，请参阅 Microsoft 文档中的[创建 SQL Server Agent 作业以对数据库邮件消息和事件日志进行存档](https://docs.microsoft.com/en-us/sql/relational-databases/database-mail/create-a-sql-server-agent-job-to-archive-database-mail-messages-and-event-logs)。

**如欲删除所有电子邮件**
+ 使用以下 SQL 语句。

  ```
  DECLARE @GETDATE datetime
  SET @GETDATE = GETDATE();
  EXECUTE msdb.dbo.rds_sysmail_delete_mailitems_sp @sent_before = @GETDATE;
  GO
  ```

**如欲删除具有特定状态的所有电子邮件**
+ 使用以下 SQL 语句删除所有失败的消息。

  ```
  DECLARE @GETDATE datetime
  SET @GETDATE = GETDATE();
  EXECUTE msdb.dbo.rds_sysmail_delete_mailitems_sp @sent_status = 'failed';
  GO
  ```

# 启动和停止邮件队列
<a name="SQLServer.DBMail.StartStop"></a>

使用以下说明启动和停止数据库邮件队列：

**Topics**
+ [启动邮件队列](#SQLServer.DBMail.Start)
+ [停止邮件队列](#SQLServer.DBMail.Stop)

## 启动邮件队列
<a name="SQLServer.DBMail.Start"></a>

您可以使用 `rds_sysmail_control` 存储过程启动数据库邮件过程。

**注意**  
启用数据库邮件会自动启动邮件队列。

**如欲启动邮件队列**
+ 使用以下 SQL 语句。

  ```
  EXECUTE msdb.dbo.rds_sysmail_control start;
  GO
  ```

## 停止邮件队列
<a name="SQLServer.DBMail.Stop"></a>

您可以使用 `rds_sysmail_control` 存储过程停止数据库邮件过程。

**如欲停止邮件队列**
+ 使用以下 SQL 语句。

  ```
  EXECUTE msdb.dbo.rds_sysmail_control stop;
  GO
  ```

## 使用文件附件
<a name="SQLServer.DBMail.Files"></a>

在 SQL Server 上，来自 RDS 的数据库邮件消息不支持以下文件扩展名：.ade、.adp、.apk、.appx、.appxbundle、.bat、.bak、.cab、.chm、.cmd、.com、.cpl、.dll、.dmg、.exe、.hta、.inf1、.ins、.isp、.iso、.jar、.job、.js、.jse、.ldf、.lib、.lnk、.mde、.mdf、.msc、.msi、.msix、.msixbundle、.msp、.mst、.nsh、.pif、.ps、.ps1、.psc1、.reg、.rgs、.scr、.sct、.shb、.shs、.svg、.sys、.u3p、.vb、.vbe、.vbs、.vbscript、.vxd、.ws、.wsc、.wsf 和.wsh。

数据库邮件使用当前用户的 Microsoft Windows 安全环境来控制对文件的访问。使用 SQL Server 身份验证登录的用户无法使用带 `@file_attachments` 存储过程的 `sp_send_dbmail` 参数来附加文件。Windows 不允许 SQL Server 从一台远程计算机向另一台远程计算机提供凭证。因此，当命令从运行 SQL Server 的计算机以外的计算机运行时，数据库邮件无法从网络共享中的附加文件。

但是，您可以使用 SQL Server Agent 作业来附加文件。有关 SQL Server Agent 的详细信息，请参阅 Microsoft 文档中的 [使用 SQL Server Agent for Amazon RDS](Appendix.SQLServer.CommonDBATasks.Agent.md) 和 [SQL Server Agent](https://docs.microsoft.com/en-us/sql/ssms/agent/sql-server-agent)。

## 多可用区部署的注意事项
<a name="SQLServer.DBMail.MAZ"></a>

在多可用区数据库实例上配置数据库邮件时，配置不会自动传播到辅助节点。我们建议将多可用区实例转换为单可用区实例，配置数据库邮件，然后将数据库实例转换回多可用区实例。然后，主节点和辅助节点都具有数据库邮件配置。

如果您从配置了数据库邮件的多可用区实例中创建只读副本，则副本将继承配置，但不会向 SMTP 服务器提供密码。使用密码更新数据库邮件账户。

## 删除 SMTP（端口 25）限制
<a name="SQLServer.DBMail.SMTP"></a>

默认情况下，AWS 会阻止 RDS for SQL Server 数据库实例的 SMTP（端口 25）上的出站流量。这样做是为了根据弹性网络接口所有者的策略来阻止垃圾邮件。如果需要，您可以删除此限制。有关更多信息，请参阅[如何删除 Amazon EC2 实例或 Lambda 函数的端口 25 的限制？](https://repost.aws/knowledge-center/ec2-port-25-throttle)。