

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

# 使用从 SQL Server 迁移到 PostgreSQL AWS Schema Conversion Tool
<a name="CHAP_Source.SQLServer.ToPostgreSQL"></a>

您可以在 AWS SCT中使用 SQL Server 到 PostgreSQL 的扩展包。此扩展包在转换后的 PostgreSQL 代码中模拟 SQL Server 数据库函数。使用 SQL Server 到 PostgreSQL 扩展包模拟 SQL Server Agent 和 SQL Server 数据库邮件。有关扩展包的更多信息，请参阅[将扩展包与 AWS Schema Conversion Tool](CHAP_ExtensionPack.md)。

**Topics**
+ [将 PostgreSQL 用作目标数据库的权限](#CHAP_Source.SQLServer.ToPostgreSQL.ConfigurePostgreSQL)
+ [SQL Server 到 PostgreSQL 的转换设置](#CHAP_Source.SQLServer.ToPostgreSQL.ConversionSettings)
+ [将 SQL Server 分区转换为 PostgreSQL 版本 10 分区](#CHAP_Source.SQLServer.ToPostgreSQL.PG10Partitions)
+ [迁移注意事项](#CHAP_Source.SQLServer.ToPostgreSQL.MigrationConsiderations)
+ [在 PostgreSQL 中使用 AWS SCT 扩展包模拟 SQL Server 代理](CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.md)
+ [在 PostgreSQL 中使用 AWS SCT 扩展包模拟 SQL Server 数据库邮件](CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Mail.md)

## 将 PostgreSQL 用作目标数据库的权限
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ConfigurePostgreSQL"></a>

要使用 PostgreSQL 作为目标 AWS SCT ，需要权限。`CREATE ON DATABASE`请确保为每个目标 PostgreSQL 数据库授予此权限。

要使用转换后的公共同义词，请将数据库的默认搜索路径更改为 `"$user", public_synonyms, public`。

您可以使用以下代码示例创建数据库用户并授予权限。

```
CREATE ROLE user_name LOGIN PASSWORD 'your_password';
GRANT CREATE ON DATABASE db_name TO user_name;
ALTER DATABASE db_name SET SEARCH_PATH = "$user", public_synonyms, public;
```

在前面的示例中，*user\$1name*使用您的用户名替换。然后，*db\$1name*替换为目标数据库的名称。最后，*your\$1password*替换为安全密码。

在 PostgreSQL 中，只有架构所有者或 `superuser` 才能删除架构。即使架构的所有者并不拥有架构的某些对象，该所有者也可以删除该架构及其包含的所有对象。

当你使用不同的用户转换不同的架构并将其应用到目标数据库时，当无法删除架构时，你 AWS SCT 可能会收到一条错误消息。要避免出现此错误消息，请使用 `superuser` 角色。

## SQL Server 到 PostgreSQL 的转换设置
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ConversionSettings"></a>

要编辑 SQL Server 到 PostgreSQL 的转换设置，请选择**设置**，然后选择**转换设置**。从上方的列表中选择 **SQL Server**，然后选择 **SQL Server – PostgreSQL**。 AWS SCT 显示 SQL Server 到 PostgreSQL 转换的所有可用设置。

中的 SQL Server 到 PostgreSQL 的转换设置包括以下 AWS SCT 各项的选项：
+ 限制转换后的代码中操作项的注释数量。

  对于在**转换后的代码中为所选严重性及更高的措施项添加注释**，请选择措施项的严重性。 AWS SCT 在转换后的代码中为选定严重性及更高的措施项添加注释。

  例如，要最大限度地减少转换后的代码中的注释数量，请选择**仅错误**。要在转换后的代码中包含所有操作项的注释，请选择**所有消息**。
+ 允许在 SQL Server 的不同表中使用同名索引。

  在 PostgreSQL 中，架构中使用的所有索引名称都必须是唯一的。要确保为所有索引 AWS SCT 生成唯一的名称，请选择 “**为索引生成唯一名称**”。
+ 将 SQL Server 过程转换为 PostgreSQL 函数。

  PostgreSQL 版本 10 及更早版本不支持过程。对于不熟悉 PostgreSQL 中使用过程的客户 AWS SCT ，可以将过程转换为函数。为此，请选择**将过程转换为函数**。
+ 在表中模拟 `EXEC` 的输出。

  源 SQL Server 数据库可以将 `EXEC` 的输出存储在表中。 AWS SCT 创建临时表和模拟此功能的附加过程。要使用此模拟，请选择**创建额外的例程处理开放数据集**。
+ 定义要在转换后的代码中用于架构名称的模板。对于**架构名称生成模板**，选择以下选项之一：
  + **<source\$1db>**：使用 SQL Server 数据库名称作为 PostgreSQL 中的架构名称。
  + **<source\$1schema>**：使用 SQL Server 架构名称作为 PostgreSQL 中的架构名称。
  + **<source\$1db>\$1<schema>**：使用 SQL Server 数据库名称和架构名称的组合作为 PostgreSQL 中的架构名称。
+ 保持源对象名称的字母大小写。

  要避免将对象名称转换为小写，请选择**避免将区分大小写的操作转换为小写**。仅当您在目标数据库中启用区分大小写选项时，此选项才适用。
+ 保留源数据库中的参数名称。

  要在转换后的代码中为参数名称添加双引号，请选择**保留原始参数名称**。

## 将 SQL Server 分区转换为 PostgreSQL 版本 10 分区
<a name="CHAP_Source.SQLServer.ToPostgreSQL.PG10Partitions"></a>

将 Microsoft SQL Server 数据库转换为 Amazon Aurora PostgreSQL 兼容版本 (Aurora PostgreSQL) 或适用于 PostgreSQL 的 Amazon Relational Database Service (Amazon RDS for PostgreSQL) 时，请注意以下几点：

在 SQL Server 中，使用分区函数创建分区。从 SQL Server 分区表转换为 PostgreSQL 版本 10 分区表时，请注意一些潜在问题：
+ SQL Server 允许使用无 NOT NULL 约束的列为表分区。在此情况下，所有 NULL 值都将转到最左边的分区。PostgreSQL 不支持 RANGE 分区采用 NULL 值。
+ SQL Server 允许为分区表创建主键和唯一键。对于 PostgreSQL，直接为每个分区创建主键或唯一键。因此，迁移到 PostgreSQL 时，必须从父表中删除 PRIMARY 或 UNIQUE KEY 约束。生成的键名称采用格式 `<original_key_name>_<partition_number>`。
+ SQL Server 允许创建进出分区表的外键约束。PostgreSQL 不支持引用分区表的外键。此外，PostgreSQL 不支持从一个分区表到另一个表的外键引用。
+ SQL Server 允许为分区表创建索引。对于 PostgreSQL，应直接为每个分区创建一个索引。因此，迁移到 PostgreSQL 时，索引必须从其父表中删除。生成的索引名称采用格式 `<original_index_name>_<partition_number>`。
+  PostgreSQL 不支持分区索引。

## 迁移注意事项
<a name="CHAP_Source.SQLServer.ToPostgreSQL.MigrationConsiderations"></a>

将 SQL Server 架构迁移到 PostgreSQL 时要考虑的一些事项：
+ 在 PostgreSQL 中，架构中所有对象 (包括索引) 的名称必须是唯一的。索引名称在基表的架构中必须是唯一的。在 SQL Server 中，索引名称可与其他表的相同。

  为了确保索引名称的唯一性，如果您的索引名称不是唯一的，则 AWS SCT 可以选择生成唯一的索引名称。为此，请选择项目属性中的 **Generate unique index names (生成唯一索引名称)**。默认情况下，此选项处于启用状态。如果此选项处于启用状态，将使用格式 IX\$1table\$1name\$1index\$1name 创建唯一索引名称。如果此选项处于禁用状态，则不会更改索引名称。
+ 一个 GOTO 语句和一个标签可用于更改语句的运行顺序。将跳过接在 GOTO 语句后的任何 Transact-SQL 语句并且处理将在标签处继续。GOTO 语句和标签可在过程、批处理或语句块中的任意位置使用。GOTO 语句也可以嵌套。

  PostgreSQL 不使用 GOTO 语句。当 AWS SCT 转换包含 GOTO 语句的代码时，它会将该语句转换为使用 BEGIN... END 或 LOOP... END LOOP 语句。您可以在下表中找到如何 AWS SCT 转换 GOTO 语句的示例。  
**SQL Server GOTO 语句和已转换的 PostgreSQL 语句**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/SchemaConversionTool/latest/userguide/CHAP_Source.SQLServer.ToPostgreSQL.html)
+ PostgreSQL 不支持合并语句。 AWS SCT 通过以下方式模拟 MERGE 语句的行为：
  + 通过 INSERT ON CONFLICT 结构。
  + 通过使用 UPDATE FROM DML 语句，例如没有 WHEN NOT MATCHED 子句的 MERGE。
  + 通过使用 CURSOR（如带有 DELETE 子句的 MERGE）或复杂的 MERGE ON 条件语句。
+ AWS SCT 当目标为 Amazon RDS 时，可以将数据库触发器添加到对象树中。
+ AWS SCT 当目标为 Amazon RDS 时，可以在对象树中添加服务器级触发器。
+ SQL Server 会自动创建和管理 `deleted` 和 `inserted` 表。您可以使用这些临时的、驻留在内存中的表来测试某些数据修改的效果以及为 DML 触发器操作设置条件。 AWS SCT 可以在 DML 触发器语句中转换这些表的用法。
+ AWS SCT 当目标为 Amazon RDS 时，可以将链接服务器添加到对象树中。
+ 在从 Microsoft SQL Server 迁移到 PostgreSQL 时，内置的 SUSER\$1SNAME 函数进行如下转换：
  + SUSER\$1SNAME – 返回与安全标识号 (SID) 关联的登录名。
  + SUSER\$1SNAME(<server\$1user\$1sid>) – 不受支持。
  + SUSER\$1SNAME() CURRENT\$1USER – 返回当前执行上下文的用户名。
  + SUSER\$1SNAME(NULL) – 返回 NULL。
+ 支持转换表值函数。表值函数返回一个表，并且可在查询中代替表。
+ PATINDEX 在所有有效的文本和字符数据类型上返回指定表达式中模式的第一个匹配项的起始位置。如果找不到该模式，则返回零。<pattern character><expression character varying>从 SQL Server 转换为适用于 PostgreSQL 的亚马逊 RDS 时 AWS SCT ，将使用 PATINDEX 的应用程序代码替换为 aws\$1sqlserver\$1ext.patindex (,)。
+ 在 SQL Server 中，用户定义的表类型是表示表结构的定义的类型。可以使用用户定义的表类型来声明存储过程或函数的表值参数。也可以使用用户定义的表类型来声明要在批处理中或存储过程或函数主体中使用的表变量。 AWS SCT 通过创建临时表在 PostgreSQL 中模拟了这种类型。

从 SQL Server 转换为 PostgreSQL 时 AWS SCT ，会将 SQL Server 系统对象转换为 PostgreSQL 中可识别的对象。下表显示了如何转换系统对象。

 


| MS SQL Server 使用案例 | PostgreSQL 替代项 | 
| --- | --- | 
| SYS.SCHEMAS | AWS\$1SQLSERVER\$1EXT.SYS\$1SCHEMAS | 
| SYS.TABLES | AWS\$1SQLSERVER\$1EXT.SYS\$1TABLES | 
| SYS.VIEWS | AWS\$1SQLSERVER\$1EXT.SYS\$1Views | 
| SYS.ALL\$1VIEWS | AWS\$1SQLSERVER\$1EXT.SYS\$1ALL\$1VIEWS | 
| SYS.TYPES | AWS\$1SQLSERVER\$1EXT.SYS\$1TYPE | 
| SYS.COLUMNS | AWS\$1SQLSERVER\$1EXT.SYS\$1COLUMN | 
| SYS.ALL\$1COLUMNS | AWS\$1SQLSERVER\$1EXT.SYS\$1ALL\$1COLUMNS | 
| SYS.FOREIGN\$1KEYS | AWS\$1SQLSERVER\$1EXT.SYS\$1FOREIGN\$1K | 
| SYS.SYSFOREIGNKEYS | AWS\$1SQLSERVER\$1EXT.SYS\$1SYSFOREIGNK | 
| SYS.FOREIGN\$1KEY\$1COLUMNS | AWS\$1SQLSERVER\$1EXT.SYS\$1FOREIGN\$1KEY\$1CO | 
| SYS.KEY\$1CONSTRAINTS | AWS\$1SQLSERVER\$1EXT.SYS\$1KEY\$1KEY\$1 | 
| SYS.IDENTITY\$1COLUMNS | AWS\$1SQLSERVER\$1EXT.SYS\$1IDTITY\$1COLUMNS | 
| SYS.PROCEDURES | AWS\$1SQLSERVER\$1EXT.SYS\$1程序 | 
| SYS.INDEXES | AWS\$1SQLSERVER\$1EXT.SYS\$1indexes | 
| SYS.SYSINDEXES | AWS\$1SQLSERVER\$1EXT.SYS\$1SYSINDEXS | 
| SYS.OBJECTS | AWS\$1SQLSERVER\$1EXT.SYS\$1OBJEC | 
| SYS.ALL\$1OBJECTS | AWS\$1SQLSERVER\$1EXT.SYS\$1ALL\$1OBJECT | 
| SYS.SYSOBJECTS | AWS\$1SQLSERVER\$1EXT.SYS\$1SYSOBJECTS | 
| SYS.SQL\$1MODULES | AWS\$1SQLSERVER\$1EXT.SYS\$1SQL\$1MODULES | 
| SYS.DATABASES | AWS\$1SQLSERVER\$1EXT.SYS\$1数据库 | 
| INFORMATION\$1SCHEMA.SCHEMATA  | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1SC | 
| INFORMATION\$1SCHEMA.VIEWS | AWS\$1SQLSERVER\$1扩展信息\$1架构\$1视图 | 
| INFORMATION\$1SCHEMA.TABLES | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1 | 
| INFORMATION\$1SCHEMA.COLUMNS | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1 | 
| INFORMATION\$1SCHEMA.CHECK\$1CONSTRAINTS | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1CHECK | 
| INFORMATION\$1SCHEMA.REFERENTIAL\$1CONSTRAINTS | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1referencial\$1 | 
| INFORMATION\$1SCHEMA.TABLE\$1CONSTRAINTS | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1TABLE\$1 | 
| INFORMATION\$1SCHEMA.KEY\$1COLUMN\$1USAGE | AWS\$1SQLSERVER\$1EXT.INFORMATION \$1SCHEMA\$1KEY\$1COLUMN\$1 | 
| INFORMATION\$1SCHEMA.CONSTRAINT\$1TABLE\$1USAGE | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1CONSTRAINT\$1TABLE\$1USAGE  | 
| INFORMATION\$1SCHEMA.CONSTRAINT\$1COLUMN\$1USAGE | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1CONSTRAINT\$1COLUMN\$1USAGE  | 
| INFORMATION\$1SCHEMA.ROUTINES | AWS\$1SQLSERVER\$1EXT.INFORMATION\$1SCHEMA\$1例程 | 
| SYS.SYSPROCESSES | AWS\$1SQLSERVER\$1EXT.SYS\$1SYSPROCESS | 
| sys.system\$1objects | AWS\$1SQLSERVER\$1EXT.SYSTEM\$1OBJECTS | 

# 在 PostgreSQL 中使用 AWS SCT 扩展包模拟 SQL Server 代理
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent"></a>

SQL Server Agent 是运行 SQL Server 作业的 Microsoft Windows 服务。SQL Server Agent 可以根据计划、为响应特定事件或者按需运行作业。有关 SQL Server Agent 的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/ssms/agent/sql-server-agent?view=sql-server-ver15)。

PostgreSQL 没有 SQL Server Agent 的等效服务。要模拟 SQL Server 代理功能，请 AWS SCT 创建一个扩展包。此扩展包使用 AWS Lambda 和 Amazon CloudWatch。 AWS Lambda 实现用于管理计划和运行作业的接口。亚马逊 CloudWatch 维护计划规则。

AWS Lambda 而且 Amazon CloudWatch 使用 JSON 参数进行交互。此 JSON 参数具有以下结构。

```
{
    "mode": mode,
    "parameters": {
        list of parameters
    },
    "callback": procedure name
}
```

在前面的示例中，*`mode`* 是任务的类型，`list of parameters` 是一组取决于任务类型的参数。此外，`procedure name` 是任务完成后运行的过程的名称。

AWS SCT 使用一个 Lambda 函数来控制和运行作业。该 CloudWatch 规则开始运行作业，并提供启动作业所需的必要信息。当 CloudWatch 规则触发时，它会使用规则中的参数启动 Lambda 函数。

要创建调用过程的简单作业，请使用以下格式。

```
{
    "mode": "run_job",
    "parameters": {
        "vendor": "mysql",
        "cmd": "lambda_db.nightly_job"
    }
}
```

要创建多个步骤作业，请使用以下格式。

```
{
    "mode": "run_job",
    "parameters": {
        "job_name": "Job1",
        "enabled": "true",
        "start_step_id": 1,
        "notify_level_email": [0|1|2|3],
        "notify_email": email,
        "delete_level": [0|1|2|3],
        "job_callback": "ProcCallBackJob(job_name, code, message)",
        "step_callback": "ProcCallBackStep(job_name, step_id, code, message)"
    },
    "steps": [
        {
            "id":1,
            "cmd": "ProcStep1",
            "cmdexec_success_code": 0,
            "on_success_action": [|2|3|4],
            "on_success_step_id": 1,
            "on_fail_action": 0,
            "on_fail_step_id": 0,
            "retry_attempts": number,
            "retry_interval": number
        },
        {
            "id":2,
            "cmd": "ProcStep2",
            "cmdexec_success_code": 0,
            "on_success_action": [1|2|3|4],
            "on_success_step_id": 0,
            "on_fail_action": 0,
            "on_fail_step_id": 0,
            "retry_attempts": number,
            "retry_interval": number
        },
        ...
]
}
```

为了模拟 PostgreSQL 中的 SQL Server 代理行为， AWS SCT 扩展包还创建了以下表格和过程。

## 在 PostgreSQL 中模拟 SQL Server Agent 的表
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Tables"></a>

为了模拟 SQL Server Agent，扩展包使用以下表：

**sysjobs**  
存储有关作业的信息。

**sysjobsteps**  
存储有关作业步骤的信息。

**sysschedules**  
存储有关作业计划的信息。

**sysjobschedules**  
存储各个作业的计划信息。

**sysjobhistory**  
存储有关计划作业运行的信息。

## 在 PostgreSQL 中模拟 SQL Server Agent 的过程
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Procedures"></a>

要模拟 SQL Server Agent，扩展包使用以下过程：

**sp\$1add\$1job**  
添加新作业。

**sp\$1add\$1jobstep**  
向作业添加步骤。

**sp\$1add\$1schedule**  
在 Amazon 中创建新的计划规则 CloudWatch。您可以将此计划用于任意数量的作业。

**sp\$1attach\$1schedule**  
设置所选作业的计划。

**sp\$1add\$1jobschedule**  
在 Amazon CloudWatch 中为任务创建计划规则并为该规则设定目标。

**sp\$1update\$1job**  
更新先前创建的作业的属性。

**sp\$1update\$1jobstep**  
更新作业中步骤的属性。

**sp\$1update\$1schedule**  
更新 Amazon 中计划规则的属性 CloudWatch。

**sp\$1update\$1jobschedule**  
更新指定作业计划的属性。

**sp\$1delete\$1job**  
删除作业。

**sp\$1delete\$1jobstep**  
从作业中删除一个作业步骤。

**sp\$1delete\$1schedule**  
删除计划。

**sp\$1delete\$1jobschedule**  
从 Amazon 中删除指定任务的计划规则 CloudWatch。

**sp\$1detach\$1schedule**  
移除计划和作业之间的关联。

**get\$1jobs、update\$1job**  
与之交互的内部程序 AWS Elastic Beanstalk。

**sp\$1verify\$1job\$1date、sp\$1verify\$1job\$1time、sp\$1verify\$1job、sp\$1verify\$1jobstep、sp\$1verify\$1schedule、sp\$1verify\$1job\$1identifiers、sp\$1verify\$1schedule\$1identifiers**  
检查设置的内部过程。

## 在 PostgreSQL 中模拟 SQL Server Agent 的过程的语法
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.Syntax"></a>

扩展包中的 `aws_sqlserver_ext.sp_add_job` 过程模拟 `msdb.dbo.sp_add_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-job-transact-sql?view=sql-server-ver15)。

```
par_job_name varchar,
par_enabled smallint = 1,
par_description varchar = NULL::character varying,
par_start_step_id integer = 1,
par_category_name varchar = NULL::character varying,
par_category_id integer = NULL::integer,
par_owner_login_name varchar = NULL::character varying,
par_notify_level_eventlog integer = 2,
par_notify_level_email integer = 0,
par_notify_level_netsend integer = 0,
par_notify_level_page integer = 0,
par_notify_email_operator_name varchar = NULL::character varying,
par_notify_netsend_operator_name varchar = NULL::character varying,
par_notify_page_operator_name varchar = NULL::character varying,
par_delete_level integer = 0,
inout par_job_id integer = NULL::integer,
par_originating_server varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_jobstep` 过程模拟 `msdb.dbo.sp_add_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-jobstep-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_step_id integer = NULL::integer,
par_step_name varchar = NULL::character varying,
par_subsystem varchar = 'TSQL'::bpchar,
par_command text = NULL::text,
par_additional_parameters text = NULL::text,
par_cmdexec_success_code integer = 0,
par_on_success_action smallint = 1,
par_on_success_step_id integer = 0,
par_on_fail_action smallint = 2,
par_on_fail_step_id integer = 0,
par_server varchar = NULL::character varying,
par_database_name varchar = NULL::character varying,
par_database_user_name varchar = NULL::character varying,
par_retry_attempts integer = 0,
par_retry_interval integer = 0,
par_os_run_priority integer = 0,
par_output_file_name varchar = NULL::character varying,
par_flags integer = 0,
par_proxy_id integer = NULL::integer,
par_proxy_name varchar = NULL::character varying,
inout par_step_uid char = NULL::bpchar,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_schedule` 过程模拟 `msdb.dbo.sp_add_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_name varchar,
par_enabled smallint = 1,
par_freq_type integer = 0,
par_freq_interval integer = 0,
par_freq_subday_type integer = 0,
par_freq_subday_interval integer = 0,
par_freq_relative_interval integer = 0,
par_freq_recurrence_factor integer = 0,
par_active_start_date integer = NULL::integer,
par_active_end_date integer = 99991231,
par_active_start_time integer = 0,
par_active_end_time integer = 235959,
par_owner_login_name varchar = NULL::character varying,
*inout par_schedule_uid char = NULL::bpchar,*
inout par_schedule_id integer = NULL::integer,
par_originating_server varchar = NULL::character varying,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_attach_schedule` 过程模拟 `msdb.dbo.sp_attach_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-attach-schedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_add_jobschedule` 过程模拟 `msdb.dbo.sp_add_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-add-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_name varchar = NULL::character varying,
par_enabled smallint = 1,
par_freq_type integer = 1,
par_freq_interval integer = 0,
par_freq_subday_type integer = 0,
par_freq_subday_interval integer = 0,
par_freq_relative_interval integer = 0,
par_freq_recurrence_factor integer = 0,
par_active_start_date integer = NULL::integer,
par_active_end_date integer = 99991231,
par_active_start_time integer = 0,
par_active_end_time integer = 235959,
inout par_schedule_id integer = NULL::integer,
par_automatic_post smallint = 1,
inout par_schedule_uid char = NULL::bpchar,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_job` 过程模拟 `msdb.dbo.sp_delete_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-job-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_originating_server varchar = NULL::character varying,
par_delete_history smallint = 1,
par_delete_unused_schedule smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_jobstep` 过程模拟 `msdb.dbo.sp_delete_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-jobsteplog-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_step_id integer = NULL::integer,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_jobschedule` 过程模拟 `msdb.dbo.sp_delete_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_name varchar = NULL::character varying,
par_keep_schedule integer = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_delete_schedule` 过程模拟 `msdb.dbo.sp_delete_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_force_delete smallint = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_detach_schedule` 过程模拟 `msdb.dbo.sp_detach_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-detach-schedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer,
par_job_name varchar = NULL::character varying,
par_schedule_id integer = NULL::integer,
par_schedule_name varchar = NULL::character varying,
par_delete_unused_schedule smallint = 0,
par_automatic_post smallint = 1,
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_job` 过程模拟 `msdb.dbo.sp_update_job` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-job-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_description varchar = NULL::character varying
par_start_step_id integer = NULL::integer
par_category_name varchar = NULL::character varying
par_owner_login_name varchar = NULL::character varying
par_notify_level_eventlog integer = NULL::integer
par_notify_level_email integer = NULL::integer
par_notify_level_netsend integer = NULL::integer
par_notify_level_page integer = NULL::integer
par_notify_email_operator_name varchar = NULL::character varying
par_notify_netsend_operator_name varchar = NULL::character varying
par_notify_page_operator_name varchar = NULL::character varying
par_delete_level integer = NULL::integer
par_automatic_post smallint = 1
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_jobschedule` 过程模拟 `msdb.dbo.sp_update_jobschedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-jobschedule-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_freq_type integer = NULL::integer
par_freq_interval integer = NULL::integer
par_freq_subday_type integer = NULL::integer
par_freq_subday_interval integer = NULL::integer
par_freq_relative_interval integer = NULL::integer
par_freq_recurrence_factor integer = NULL::integer
par_active_start_date integer = NULL::integer
par_active_end_date integer = NULL::integer
par_active_start_time integer = NULL::integer
                par_active_end_time integer = NULL::integer
par_automatic_post smallint = 1
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_jobstep` 过程模拟 `msdb.dbo.sp_update_jobstep` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-jobstep-transact-sql?view=sql-server-ver15)。

```
par_job_id integer = NULL::integer
par_job_name varchar = NULL::character varying
par_step_id integer = NULL::integer
par_step_name varchar = NULL::character varying
par_subsystem varchar = NULL::character varying
par_command text = NULL::text
par_additional_parameters text = NULL::text
par_cmdexec_success_code integer = NULL::integer
par_on_success_action smallint = NULL::smallint
par_on_success_step_id integer = NULL::integer
par_on_fail_action smallint = NULL::smallint
par_on_fail_step_id integer = NULL::integer
par_server varchar = NULL::character varying
par_database_name varchar = NULL::character varying
par_database_user_name varchar = NULL::character varying
par_retry_attempts integer = NULL::integer
par_retry_interval integer = NULL::integer
par_os_run_priority integer = NULL::integer
par_output_file_name varchar = NULL::character varying
par_flags integer = NULL::integer
par_proxy_id integer = NULL::integer
par_proxy_name varchar = NULL::character varying
out returncode integer
```

扩展包中的 `aws_sqlserver_ext.sp_update_schedule` 过程模拟 `msdb.dbo.sp_update_schedule` 过程。有关源 SQL Server Agent 过程的详细信息，请参阅 [Microsoft 技术文档](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-update-schedule-transact-sql?view=sql-server-ver15)。

```
par_schedule_id integer = NULL::integer
par_name varchar = NULL::character varying
par_new_name varchar = NULL::character varying
par_enabled smallint = NULL::smallint
par_freq_type integer = NULL::integer
par_freq_interval integer = NULL::integer
par_freq_subday_type integer = NULL::integer
par_freq_subday_interval integer = NULL::integer
par_freq_relative_interval integer = NULL::integer
par_freq_recurrence_factor integer = NULL::integer
par_active_start_date integer = NULL::integer
par_active_end_date integer = NULL::integer
par_active_start_time integer = NULL::integer
par_active_end_time integer = NULL::integer
par_owner_login_name varchar = NULL::character varying
par_automatic_post smallint = 1
out returncode integer
```

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

要添加新作业，请使用如下所示的 `aws_sqlserver_ext.sp_add_job` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_job (
    par_job_name := 'test_job',
    par_enabled := 1::smallint,
    par_start_step_id := 1::integer,
    par_category_name := '[Uncategorized (Local)]',
    par_owner_login_name := 'sa');
```

要添加新的作业步骤，请使用如下所示的 `aws_sqlserver_ext.sp_add_jobstep` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_jobstep (
    par_job_name := 'test_job',
    par_step_id := 1::smallint,
    par_step_name := 'test_job_step1',
    par_subsystem := 'TSQL',
    par_command := 'EXECUTE [dbo].[PROC_TEST_JOB_STEP1];',
    par_server := NULL,
    par_database_name := 'GOLD_TEST_SS');
```

要添加简单的计划，请使用如下所示的 `aws_sqlserver_ext.sp_add_schedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_schedule(
    par_schedule_name := 'RunOnce',
    par_freq_type := 1,
    par_active_start_time := 233000);
```

要为作业设置计划，请使用如下所示的 `aws_sqlserver_ext.sp_attach_schedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_attach_schedule (
    par_job_name := 'test_job',
    par_schedule_name := 'NightlyJobs');
```

要为作业创建计划，请使用如下所示的 `aws_sqlserver_ext.sp_add_jobschedule` 过程。

```
SELECT * FROM aws_sqlserver_ext.sp_add_jobschedule (
    par_job_name := 'test_job2',
    par_name := 'test_schedule2',
    par_enabled := 1::smallint,
    par_freq_type := 4,
    par_freq_interval := 1,
    par_freq_subday_type := 4,
    par_freq_subday_interval := 1,
    par_freq_relative_interval := 0,
    par_freq_recurrence_factor := 0,
    par_active_start_date := 20100801,
    par_active_end_date := 99991231,
    par_active_start_time := 0,
    par_active_end_time := 0);
```

## 在 PostgreSQL 中模拟 SQL Server Agent 的使用案例示例
<a name="CHAP_Source.SQLServer.ToPostgreSQL.ExtensionPack.Agent.UseCases"></a>

如果您的源数据库代码使用 SQL Server 代理来运行作业，则可以使用 SQL Server 到 PostgreSQL 扩展包 AWS SCT 将此代码转换为 PostgreSQL。扩展包使用 AWS Lambda 函数来模拟 SQL Server 代理的行为。

您可以创建新 AWS Lambda 函数或注册现有函数。

**创建新 AWS Lambda 函数**

1. 在目标数据库树中 AWS SCT，打开上下文（右键单击）菜单，选择 “**应用扩展包**”，然后选择 P **ostgreSQL**。

   扩展包向导随即出现。

1. 在 **SQL Server Agent 模拟服务**选项卡上，执行以下操作：
   + 选择**创建 AWS Lambda 函数**。
   + 在**数据库登录名**中，输入目标数据库用户名。
   + 在**数据库密码**中，输入您在上一步中输入的用户名的密码。
   + 对于 **Python 库文件夹**，请输入 Python 库文件夹的路径。
   + 选择 “**创建 AWS Lambda 函数**”，然后选择 “**下一步**”。

**注册之前部署的 AWS Lambda 函数**
+ 在目标数据库上运行以下脚本。

  ```
  SELECT
      FROM aws_sqlserver_ext.set_service_setting(
          p_service := 'JOB', 
          p_setting := 'LAMBDA_ARN', 
          p_value := ARN)
  ```

  在上述示例中，*`ARN`* 是已部署 AWS Lambda 函数的 Amazon 资源名称（ARN）。

以下示例创建了一个由一个步骤组成的简单任务。此任务每五分钟运行一次先前创建的 `job_example` 函数。此函数将记录插入 `job_example_table` 表中。

**创建这个简单的任务**

1. 使用 `aws_sqlserver_ext.sp_add_job` 函数创建作业，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_job (
           par_job_name := 'test_simple_job');
   ```

1. 使用 `aws_sqlserver_ext.sp_add_jobstep` 函数创建任务步骤，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_jobstep (
           par_job_name := 'test_simple_job', 
           par_step_name := 'test_simple_job_step1', 
           par_command := 'PERFORM job_simple_example;');
   ```

   作业步骤指定函数的用途。

1. 使用 `aws_sqlserver_ext.sp_add_jobschedule` 函数为作业创建计划程序，如下所示。

   ```
   SELECT
       FROM aws_sqlserver_ext.sp_add_jobschedule (
           par_job_name := 'test_simple_job', 
           par_name := 'test_schedule', 
           par_freq_type := 4, /* Daily */
           par_freq_interval := 1, /* frequency_interval is unused */
           par_freq_subday_type := 4, /* Minutes */
           par_freq_subday_interval := 5 /* 5 minutes */);
   ```

   作业步骤指定函数的用途。

要删除此作业，请使用如下所示的 `aws_sqlserver_ext.sp_delete_job` 函数。

```
PERFORM aws_sqlserver_ext.sp_delete_job(
    par_job_name := 'PeriodicJob1'::character varying,
    par_delete_history := 1::smallint,
    par_delete_unused_schedule := 1::smallint);
```

# 在 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'
);
```