

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 PostgreSQL 中使用 AWS SCT 扩展包模拟 SQL Server 数据库邮件
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail"></a>

您可以使用 SQL Server 数据库邮件将从 SQL Server 数据库引擎或 Azure SQL 托管实例向用户发送电子邮件。这些电子邮件消息可以包含查询结果，也可以包含来自网络上任何资源的文件。有关 SQL Server 数据库邮件的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/database-mail/database-mail?view=sql-server-ver15)。

PostgreSQL 没有与 SQL Server 数据库邮件等效的内容。要模拟 SQL Server 数据库邮件功能， AWS SCT 会创建一个扩展包。此扩展包使用 AWS Lambda 亚马逊简单电子邮件服务 (Amazon SES) Service。 AWS Lambda 为用户提供了一个与 Amazon SES 电子邮件发送服务进行交互的接口。要设置此交互，请添加 Lambda 函数的 Amazon 资源名称（ARN）。

对于新的电子邮件账户，请使用以下命令。

```
do
$$
begin
PERFORM sysmail_add_account_sp (
    par_account_name :='your_account_name',
    par_email_address := 'your_account_email',
    par_display_name := 'your_account_display_name',
    par_mailserver_type := 'AWSLAMBDA'
    par_mailserver_name := 'ARN'
);
end;
$$ language plpgsql;
```

要将 Lambda 函数的 ARN 添加到现有电子邮件账户，请使用以下命令。

```
do
$$
begin
PERFORM sysmail_update_account_sp (
    par_account_name :='existind_account_name',
    par_mailserver_type := 'AWSLAMBDA'
    par_mailserver_name := 'ARN'
);
end;
$$ language plpgsql;
```

在上述示例中，*`ARN`* 是 Lambda 函数的 ARN。

为了在 PostgreSQL 中模拟 SQL Server 数据库邮件行为， AWS SCT 扩展包使用了以下表、视图和过程。

## 在 PostgreSQL 中模拟 SQL Server 数据库邮件的表
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.Tables"></a>

为了模拟 SQL Server 数据库邮件，扩展包使用以下表：

**sysmail\$1account**  
存储有关电子邮件账户的信息。

**sysmail\$1profile**  
存储有关用户配置文件的信息。

**sysmail\$1server**  
存储有关电子邮件服务器的信息。

**sysmail\$1mailitems**  
存储电子邮件消息列表。

**sysmail\$1attachments**  
每个电子邮件附件包含一行。

**sysmail\$1log**  
存储有关发送电子邮件消息的服务信息。

**sysmail\$1profileaccount**  
存储有关用户配置文件和电子邮件账户的信息。

## 在 PostgreSQL 中模拟 SQL Server 数据库邮件的视图
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.Views"></a>

要模拟 SQL Server 数据库邮件，请在 PostgreSQL 数据库中 AWS SCT 创建以下视图以确保兼容性。扩展包不使用这些视图，但转换后的代码可以查询它们。

**sysmail\$1allitems**  
包括所有电子邮件的列表。

**sysmail\$1faileditems**  
包括无法发送的电子邮件列表。

**sysmail\$1sentitems**  
包括已发送电子邮件的列表。

**sysmail\$1unsentitems**  
包括尚未发送的电子邮件列表。

**sysmail\$1mailattachments**  
包括附件列表。

## 在 PostgreSQL 中模拟 SQL Server 数据库邮件的过程
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.Procedures"></a>

要模拟 SQL Server 数据库邮件，扩展包使用以下过程：

**sp\$1send\$1dbmail**  
向指定的收件人发送电子邮件。

**sysmail\$1add\$1profile\$1sp**  
创建新的用户配置文件

**sysmail\$1add\$1account\$1sp**  
创建用于存储简单邮件传输协议 (SMTP) 凭证等信息的新电子邮件账户。

**sysmail\$1add\$1profileaccount\$1sp**  
将电子邮件账户添加到指定的用户配置文件中。

**sysmail\$1update\$1profile\$1sp**  
更改用户配置文件的属性，例如描述、名称等。

**sysmail\$1update\$1account\$1sp**  
更改现有电子邮件账户中的信息。

**sysmail\$1update\$1profileaccount\$1sp**  
更新指定用户配置文件中的电子邮件账户信息。

**sysmail\$1delete\$1profileaccount\$1sp**  
从指定的用户配置文件中删除电子邮件账户。

**sysmail\$1delete\$1account\$1sp**  
删除电子邮件账户。

**sysmail\$1delete\$1profile\$1sp**  
删除用户配置文件

**sysmail\$1delete\$1mailitems\$1sp**  
从内部表格中删除电子邮件。

**sysmail\$1help\$1profile\$1sp**  
显示有关用户配置文件的信息。

**sysmail\$1help\$1account\$1sp**  
显示有关电子邮件账户的信息。

**sysmail\$1help\$1profileaccount\$1sp**  
显示有关与用户配置文件关联的电子邮件账户的信息。

**sysmail\$1dbmail\$1json**  
为 AWS Lambda 函数生成 JSON 请求的内部过程。

**sysmail\$1verify\$1profile\$1sp、sysmail\$1verify\$1account\$1sp、sysmail\$1verify\$1addressparams\$1sp**  
检查设置的内部过程。

**sp\$1get\$1dbmail、sp\$1set\$1dbmail、sysmail\$1dbmail\$1xml**  
已弃用的内部过程。

## 在 PostgreSQL 中模拟 SQL Server 数据库邮件的过程的语法
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.Syntax"></a>

扩展包中的 `aws_sqlserver_ext.sp_send_dbmail` 过程模拟 `msdb.dbo.sp_send_dbmail` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-send-dbmail-transact-sql?view=sql-server-ver15)。

```
par_profile_name varchar = NULL::character varying,
par_recipients text = NULL::text,
par_copy_recipients text = NULL::text,
par_blind_copy_recipients text = NULL::text,
par_subject varchar = NULL::character varying,
par_body text = NULL::text,
par_body_format varchar = NULL::character varying,
par_importance varchar = 'NORMAL'::character varying,
par_sensitivity varchar = 'NORMAL'::character varying,
par_file_attachments text = NULL::text,
par_query text = NULL::text,
par_execute_query_database varchar = NULL::character varying,
par_attach_query_result_as_file smallint = 0,
par_query_attachment_filename varchar = NULL::character varying,
par_query_result_header smallint = 1,
par_query_result_width integer = 256,
par_query_result_separator VARCHAR = ' '::character varying,
par_exclude_query_output smallint = 0,
par_append_query_error smallint = 0,
par_query_no_truncate smallint = 0,
par_query_result_no_padding smallint = 0,
out par_mailitem_id integer,
par_from_address text = NULL::text,
par_reply_to text = NULL::text,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_delete_mailitems_sp` 过程模拟 `msdb.dbo.sysmail_delete_mailitems_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-delete-mailitems-sp-transact-sql?view=sql-server-ver15)。

```
par_sent_before timestamp = NULL::timestamp without time zone,
par_sent_status varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_add_profile_sp` 过程模拟 `msdb.dbo.sysmail_add_profile_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-profile-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_name varchar,
par_description varchar = NULL::character varying,
out par_profile_id integer,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_add_account_sp` 过程模拟 `msdb.dbo.sysmail_add_account_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-account-sp-transact-sql?view=sql-server-ver15)。

```
par_account_name varchar
par_email_address varchar
par_display_name varchar = NULL::character varying
par_replyto_address varchar = NULL::character varying
par_description varchar = NULL::character varying
par_mailserver_name varchar = NULL::character varying
par_mailserver_type varchar = 'SMTP'::bpchar
par_port integer = 25
par_username varchar = NULL::character varying
par_password varchar = NULL::character varying
par_use_default_credentials smallint = 0
par_enable_ssl smallint = 0
out par_account_id integer
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_add_profileaccount_sp` 过程模拟 `msdb.dbo.sysmail_add_profileaccount_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-add-profileaccount-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
par_sequence_number integer = NULL::integer,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_help_profile_sp` 过程模拟 `msdb.dbo.sysmail_help_profile_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-help-profile-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_update_profile_sp` 过程模拟 `msdb.dbo.sysmail_update_profile_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-update-profile-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_description varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_delete_profile_sp` 过程模拟 `msdb.dbo.sysmail_delete_profile_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-delete-profile-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_force_delete smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_help_account_sp` 过程模拟 `msdb.dbo.sysmail_help_account_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-help-account-sp-transact-sql?view=sql-server-ver15)。

```
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_update_account_sp` 过程模拟 `msdb.dbo.sysmail_update_account_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-update-account-sp-transact-sql?view=sql-server-ver15)。

```
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
par_email_address varchar = NULL::character varying,
par_display_name varchar = NULL::character varying,
par_replyto_address varchar = NULL::character varying,
par_description varchar = NULL::character varying,
par_mailserver_name varchar = NULL::character varying,
par_mailserver_type varchar = NULL::character varying,
par_port integer = NULL::integer,
par_username varchar = NULL::character varying,
par_password varchar = NULL::character varying,
par_use_default_credentials smallint = NULL::smallint,
par_enable_ssl smallint = NULL::smallint,
par_timeout integer = NULL::integer,
par_no_credential_change smallint = NULL::smallint,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_delete_account_sp` 过程模拟 `msdb.dbo.sysmail_delete_account_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-delete-account-sp-transact-sql?view=sql-server-ver15)。

```
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_help_profileaccount_sp` 过程模拟 `msdb.dbo.sysmail_help_profileaccount_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-help-profileaccount-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_update_profileaccount_sp` 过程模拟 `msdb.dbo.sysmail_update_profileaccount_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-update-profileaccount-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
par_sequence_number integer = NULL::integer,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sysmail_delete_profileaccount_sp` 过程模拟 `msdb.dbo.sysmail_delete_profileaccount_sp` 过程。有关源 SQL Server 数据库邮件过程的更多信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-delete-profileaccount-sp-transact-sql?view=sql-server-ver15)。

```
par_profile_id integer = NULL::integer,
par_profile_name varchar = NULL::character varying,
par_account_id integer = NULL::integer,
par_account_name varchar = NULL::character varying,
out returncode integer
```

## 使用在 PostgreSQL 中模拟 SQL Server 数据库邮件的过程的示例
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.Examples"></a>

要发送电子邮件，请使用如下所示的 `aws_sqlserver_ext.sp_send_dbmail` 过程。

```
PERFORM sp_send_dbmail (
    par_profile_name := 'Administrator',
    par_recipients := 'hello@rusgl.info',
    par_subject := 'Automated Success Message',
    par_body := 'The stored procedure finished'
);
```

以下示例演示如何通过查询结果发送电子邮件。

```
PERFORM sp_send_dbmail (
    par_profile_name := 'Administrator',
    par_recipients := 'hello@rusgl.info',
    par_subject := 'Account with id = 1',
    par_query := 'SELECT COUNT(*)FROM Account WHERE id = 1'
);
```

以下代码示例展示如何通过 HTML 代码发送电子邮件。

```
DECLARE var_tableHTML TEXT;
SET var_tableHTML := CONCAT(
    '<H1>Work Order Report</H1>',
    '<table border="1">',
    '<tr><th>Work Order ID</th><th>Product ID</th>',
    '<th>Name</th><th>Order Qty</th><th>Due Date</th>',
    '<th>Expected Revenue</th></tr>',
    '</table>'
);
PERFORM sp_send_dbmail (
    par_recipients := 'hello@rusgl.info',
    par_subject := 'Work Order List',
    par_body := var_tableHTML,
    par_body_format := 'HTML'
);
```

要删除电子邮件，请使用如下所示的 `aws_sqlserver_ext.sysmail_delete_mailitems_sp` 过程。

```
DECLARE var_GETDATE datetime;
SET var_GETDATE = NOW();
PERFORM sysmail_delete_mailitems_sp (
    par_sent_before := var_GETDATE
);
```

下面的示例说明如何删除最旧的电子邮件。

```
PERFORM sysmail_delete_mailitems_sp (
    par_sent_before := '31.12.2015'
);
```

以下示例将说明如何删除所有无法发送的电子邮件。

```
PERFORM sysmail_delete_mailitems_sp (
    par_sent_status := 'failed'
);
```

要创建新的用户配置文件，请使用如下所示的 `aws_sqlserver_ext.sysmail_add_profile_sp` 过程。

```
PERFORM sysmail_add_profile_sp (
    profile_name := 'Administrator',
    par_description := 'administrative mail'
);
```

以下示例说明如何创建新的配置文件并将唯一配置文件标识符保存在变量中。

```
DECLARE var_profileId INT;
SELECT par_profile_id
    FROM sysmail_add_profile_sp (
        profile_name := 'Administrator',
        par_description := ' Profile used for administrative mail.')
    INTO var_profileId;
    
SELECT var_profileId;
```

要创建新的电子邮件账户，请使用如下所示的 `aws_sqlserver_ext.sysmail_add_account_sp` 过程。

```
PERFORM sysmail_add_account_sp (
    par_account_name :='Audit Account',
    par_email_address := 'dba@rusgl.info',
    par_display_name := 'Test Automated Mailer',
    par_description := 'Account for administrative e-mail.',
    par_mailserver_type := 'AWSLAMBDA'
    par_mailserver_name := 'arn:aws:lambda:us-west-2:555555555555:function:pg_v3'
);
```

要将电子邮件账户添加到用户配置文件中，请按以下 `aws_sqlserver_ext.sysmail_add_profileaccount_sp` 过程操作。

```
PERFORM sysmail_add_profileaccount_sp (
    par_account_name := 'Administrator',
    par_account_name := 'Audit Account',
    par_sequence_number := 1
);
```

## 在 PostgreSQL 中模拟 SQL Server 数据库邮件的使用案例示例
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.UseCases"></a>

如果您的源数据库代码使用 SQL Server 数据库邮件发送电子邮件，则可以使用 AWS SCT 扩展包将此代码转换为 PostgreSQL。

**从 PostgreSQL 数据库发送一封电子邮件**

1. 创建和配置您的 AWS Lambda 函数。

1. 应用 AWS SCT 扩展包。

1. 使用如下所示的 `sysmail_add_profile_sp` 函数创建用户配置文件。

1. 使用如下所示的 `sysmail_add_account_sp` 函数创建电子邮件账户。

1. 使用如下所示的 `sysmail_add_profileaccount_sp` 函数，将此电子邮件账户添加到用户配置文件中。

   ```
   CREATE OR REPLACE FUNCTION aws_sqlserver_ext.
   proc_dbmail_settings_msdb()
   RETURNS void
   AS
   $BODY$
   BEGIN
   PERFORM aws_sqlserver_ext.sysmail_add_profile_sp(
       par_profile_name := 'Administrator',
       par_description := 'administrative mail'
   );
   PERFORM aws_sqlserver_ext.sysmail_add_account_sp(
       par_account_name := 'Audit Account',
       par_description := 'Account for administrative e-mail.',
       par_email_address := 'dba@rusgl.info',
       par_display_name := 'Test Automated Mailer',
       par_mailserver_type := 'AWSLAMBDA'
       par_mailserver_name := 'your_ARN'
   );
   PERFORM aws_sqlserver_ext.sysmail_add_profileaccount_sp(
       par_profile_name := 'Administrator',
       par_account_name := 'Audit Account',
       par_sequence_number := 1
   );
   END;
   $BODY$
   LANGUAGE plpgsql;
   ```

1. 使用如下所示的 `sp_send_dbmail` 函数发送电子邮件。

   ```
   CREATE OR REPLACE FUNCTION aws_sqlserver_ext.
   proc_dbmail_send_msdb()
   RETURNS void
   AS
   $BODY$
   BEGIN
   PERFORM aws_sqlserver_ext.sp_send_dbmail(
       par_profile_name := 'Administrator',
       par_recipients := 'hello@rusgl.info',
       par_body := 'The stored procedure finished',
       par_subject := 'Automated Success Message'
   );
   END;
   $BODY$
   LANGUAGE plpgsql;
   ```

要查看有关所有用户配置文件的信息，请按以下 `sysmail_help_profile_sp` 过程操作。

```
SELECT FROM aws_sqlserver_ext.sysmail_help_profile_sp();
```

以下示例显示有关特定用户配置文件的信息。

```
select from aws_sqlserver_ext.sysmail_help_profile_sp(par_profile_id := 1);
select from aws_sqlserver_ext.sysmail_help_profile_sp(par_profile_name := 'Administrator');
```

要查看有关所有电子邮件账户的信息，请使用如下所示的 `sysmail_help_account_sp` 过程。

```
select from aws_sqlserver_ext.sysmail_help_account_sp();
```

以下示例显示有关特定电子邮件账户的信息。

```
select from aws_sqlserver_ext.sysmail_help_account_sp(par_account_id := 1);
select from aws_sqlserver_ext.sysmail_help_account_sp(par_account_name := 'Audit Account');
```

要查看与用户配置文件关联的所有电子邮件账户的信息，请按以下 `sysmail_help_profileaccount_sp` 过程操作。

```
select from aws_sqlserver_ext.sysmail_help_profileaccount_sp();
```

以下示例按标识符、配置文件名称或账户名筛选记录。

```
select from aws_sqlserver_ext.sysmail_help_profileaccount_sp(par_profile_id := 1);
select from aws_sqlserver_ext.sysmail_help_profileaccount_sp(par_profile_id := 1, par_account_id := 1);
select from aws_sqlserver_ext.sysmail_help_profileaccount_sp(par_profile_name := 'Administrator');
select from aws_sqlserver_ext.sysmail_help_profileaccount_sp(par_account_name := 'Audit Account');
```

要更改用户配置文件名称或描述，请按以下 `sysmail_update_profile_sp` 过程操作。

```
select aws_sqlserver_ext.sysmail_update_profile_sp(
    par_profile_id := 2,
    par_profile_name := 'New profile name'
);
```

要更改电子邮件账户设置，请使用如下所示的 `ysmail_update_account_sp` 过程。

```
select from aws_sqlserver_ext.sysmail_update_account_sp (
    par_account_name := 'Audit Account',
    par_mailserver_name := 'arn:aws:lambda:region:XXXXXXXXXXXX:function:func_test',
    par_mailserver_type := 'AWSLAMBDA'
);
```