

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

# 使用从 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\_name}}使用您的用户名替换。然后，{{db\_name}}替换为目标数据库的名称。最后，{{your\_password}}替换为安全密码。

在 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\_db>**：使用 SQL Server 数据库名称作为 PostgreSQL 中的架构名称。
  + **<source\_schema>**：使用 SQL Server 架构名称作为 PostgreSQL 中的架构名称。
  + **<source\_db>\_<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\_table\_name\_index\_name 创建唯一索引名称。如果此选项处于禁用状态，则不会更改索引名称。
+ 一个 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\_SNAME 函数进行如下转换：
  + SUSER\_SNAME – 返回与安全标识号 (SID) 关联的登录名。
  + SUSER\_SNAME(<server\_user\_sid>) – 不受支持。
  + SUSER\_SNAME() CURRENT\_USER – 返回当前执行上下文的用户名。
  + SUSER\_SNAME(NULL) – 返回 NULL。
+ 支持转换表值函数。表值函数返回一个表，并且可在查询中代替表。
+ PATINDEX 在所有有效的文本和字符数据类型上返回指定表达式中模式的第一个匹配项的起始位置。如果找不到该模式，则返回零。<pattern character><expression character varying>从 SQL Server 转换为适用于 PostgreSQL 的亚马逊 RDS 时 AWS SCT ，将使用 PATINDEX 的应用程序代码替换为 aws\_sqlserver\_ext.patindex (,)。
+ 在 SQL Server 中，用户定义的表类型是表示表结构的定义的类型。可以使用用户定义的表类型来声明存储过程或函数的表值参数。也可以使用用户定义的表类型来声明要在批处理中或存储过程或函数主体中使用的表变量。 AWS SCT 通过创建临时表在 PostgreSQL 中模拟了这种类型。

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

 


| MS SQL Server 使用案例 | PostgreSQL 替代项 | 
| --- | --- | 
| SYS.SCHEMAS | AWS\_SQLSERVER\_EXT.SYS\_SCHEMAS | 
| SYS.TABLES | AWS\_SQLSERVER\_EXT.SYS\_TABLES | 
| SYS.VIEWS | AWS\_SQLSERVER\_EXT.SYS\_Views | 
| SYS.ALL\_VIEWS | AWS\_SQLSERVER\_EXT.SYS\_ALL\_VIEWS | 
| SYS.TYPES | AWS\_SQLSERVER\_EXT.SYS\_TYPE | 
| SYS.COLUMNS | AWS\_SQLSERVER\_EXT.SYS\_COLUMN | 
| SYS.ALL\_COLUMNS | AWS\_SQLSERVER\_EXT.SYS\_ALL\_COLUMNS | 
| SYS.FOREIGN\_KEYS | AWS\_SQLSERVER\_EXT.SYS\_FOREIGN\_K | 
| SYS.SYSFOREIGNKEYS | AWS\_SQLSERVER\_EXT.SYS\_SYSFOREIGNK | 
| SYS.FOREIGN\_KEY\_COLUMNS | AWS\_SQLSERVER\_EXT.SYS\_FOREIGN\_KEY\_CO | 
| SYS.KEY\_CONSTRAINTS | AWS\_SQLSERVER\_EXT.SYS\_KEY\_KEY\_ | 
| SYS.IDENTITY\_COLUMNS | AWS\_SQLSERVER\_EXT.SYS\_IDTITY\_COLUMNS | 
| SYS.PROCEDURES | AWS\_SQLSERVER\_EXT.SYS\_程序 | 
| SYS.INDEXES | AWS\_SQLSERVER\_EXT.SYS\_indexes | 
| SYS.SYSINDEXES | AWS\_SQLSERVER\_EXT.SYS\_SYSINDEXS | 
| SYS.OBJECTS | AWS\_SQLSERVER\_EXT.SYS\_OBJEC | 
| SYS.ALL\_OBJECTS | AWS\_SQLSERVER\_EXT.SYS\_ALL\_OBJECT | 
| SYS.SYSOBJECTS | AWS\_SQLSERVER\_EXT.SYS\_SYSOBJECTS | 
| SYS.SQL\_MODULES | AWS\_SQLSERVER\_EXT.SYS\_SQL\_MODULES | 
| SYS.DATABASES | AWS\_SQLSERVER\_EXT.SYS\_数据库 | 
| INFORMATION\_SCHEMA.SCHEMATA  | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_SC | 
| INFORMATION\_SCHEMA.VIEWS | AWS\_SQLSERVER\_扩展信息\_架构\_视图 | 
| INFORMATION\_SCHEMA.TABLES | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_ | 
| INFORMATION\_SCHEMA.COLUMNS | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_ | 
| INFORMATION\_SCHEMA.CHECK\_CONSTRAINTS | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_CHECK | 
| INFORMATION\_SCHEMA.REFERENTIAL\_CONSTRAINTS | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_referencial\_ | 
| INFORMATION\_SCHEMA.TABLE\_CONSTRAINTS | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_TABLE\_ | 
| INFORMATION\_SCHEMA.KEY\_COLUMN\_USAGE | AWS\_SQLSERVER\_EXT.INFORMATION \_SCHEMA\_KEY\_COLUMN\_ | 
| INFORMATION\_SCHEMA.CONSTRAINT\_TABLE\_USAGE | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_CONSTRAINT\_TABLE\_USAGE  | 
| INFORMATION\_SCHEMA.CONSTRAINT\_COLUMN\_USAGE | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_CONSTRAINT\_COLUMN\_USAGE  | 
| INFORMATION\_SCHEMA.ROUTINES | AWS\_SQLSERVER\_EXT.INFORMATION\_SCHEMA\_例程 | 
| SYS.SYSPROCESSES | AWS\_SQLSERVER\_EXT.SYS\_SYSPROCESS | 
| sys.system\_objects | AWS\_SQLSERVER\_EXT.SYSTEM\_OBJECTS | 