

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

# 在 Aurora PostgreSQL 中处理动态 SQL 语句中的匿名块
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql"></a>

*anuradha chintha，Amazon Web Services*

## Summary
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-summary"></a>

注意：亚马逊 Cloud Directory 不再向新客户开放。[要获取 Cloud Directory 的替代方案，请浏览[亚马逊 DynamoDB 和亚马逊](https://aws.amazon.com/dynamodb/) Neptune。](https://aws.amazon.com/neptune/)如果您需要帮助为自己的用例选择合适的替代方案，或有任何其他问题，请联系[AWS 支持](https://aws.amazon.com/support/)。

此模式向您展示了如何避免在处理动态 SQL 语句中的匿名块时出现的错误。当您使用 AWS Schema Conversion Tool 将 Oracle 数据库转换为 Aurora PostgreSQL-Compatible Edition 数据库时，您会收到一条错误消息。为避免错误，必须知道 `OUT` 绑定变量的值，但是要等到运行 SQL 语句之后才能知道 `OUT` 绑定变量的值。该错误是由于 AWS Schema Conversion Tool（AWS SCT）不理解动态 SQL 语句中的逻辑造成的。AWS SCT 无法在 PL/SQL 代码（即函数、过程和包）中转换动态 SQL 语句。

## 先决条件和限制
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-prereqs"></a>

**先决条件**
+ 有效的 Amazon Web Services account
+ [Aurora PostgreSQL 数据库（DB）实例](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.DBInstanceClass.html)
+ [Amazon Relational Database Service（Amazon RDS）for Oracle 数据库实例](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Oracle.html)
+ [PostgreSQL 交互式终端 (psql)](https://www.postgresql.org/docs/current/app-psql.html)
+ [SQL \$1Plus](https://docs.oracle.com/cd/B14117_01/server.101/b12170/qstart.htm)
+ 目标数据库中的 `AWS_ORACLE_EXT` 架构（[AWS SCT 扩展包](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_ExtensionPack.html)的一部分）
+ 最新版本的 [AWS Schema Conversion Tool（AWS SCT）](https://aws.amazon.com/dms/schema-conversion-tool/)及其所需驱动程序

## 架构
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-architecture"></a>

**源技术堆栈**
+ 本地 Oracle 数据库 10g 及更高版本

**目标技术堆栈**
+ Amazon Aurora PostgreSQL
+ Amazon RDS for PostgreSQL
+ AWS Schema Conversion Tool (AWS SCT)

**迁移架构**

下图显示了如何使用 AWS SCT 和 Oracle `OUT` 绑定变量来扫描应用程序代码中是否存在嵌入式 SQL 语句，并将代码转换为 Aurora 数据库可以使用的兼容格式。

![\[使用 AWS SCT 和 Oracle OUT 绑定变量的架构图\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/ada89410-b866-4d39-af9c-021be6cc6ae5/images/7c004981-2ed0-4b67-989f-54d8691712ca.png)


下图显示了如下工作流：

1. 使用 Aurora PostgreSQL 作为目标数据库，为源数据库生成 AWS SCT 报告。

1. 识别动态 SQL 代码块中的匿名块（AWS SCT 对此提出了错误）。

1. 手动转换代码块并将代码部署到目标数据库上。

## 工具
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-tools"></a>

**Amazon Web Services**
+ [Amazon Aurora PostgreSQL 兼容版](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraPostgreSQL.html)是一个完全托管的、与 ACID 兼容的关系数据库引擎，可帮助您建立、运行和扩展 PostgreSQL 部署。
+ [Amazon Relational Database Service (Amazon RDS) for Oracle](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) 可帮助您在 Amazon Web Services Cloud 中设置、操作和扩展 Oracle 关系数据库。
+ [AWS Schema Conversion Tool（AWS SCT）](https://aws.amazon.com/dms/schema-conversion-tool/)通过自动将源数据库架构和大部分数据库代码对象转换为与目标数据库兼容的格式，帮助您预测异构数据库迁移。

**其他工具**
+ [pgAdmin](https://www.pgadmin.org/) 允许您连接数据库服务器并与之交互。
+ [Oracle SQL Developer](https://www.oracle.com/database/sqldeveloper/) 是一个集成的开发环境，您可以使用它来开发和管理 Oracle 数据库中的数据库。您可以使用 [SQL \$1Plus](https://docs.oracle.com/cd/B19306_01/server.102/b14357/qstart.htm) 或 Oracle SQL Developer 来实现这种模式。

## 操作说明
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-epics"></a>

### 配置 Oracle 源数据库
<a name="configure-the-oracle-source-database"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在亚马逊 RDS 或亚马逊上创建 Oracle 实例 EC2。 | 要在 Amazon RDS 上创建 Oracle 数据库实例，请参阅 Amazon RDS 文档中的[创建 Oracle 数据库实例并连接到 Oracle 数据库实例上的数据库](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.Oracle.html)。要在亚马逊弹性计算云 (亚马逊 EC2) 上创建 Oracle 数据库实例，请参阅 AWS Prescriptive [ EC2 Guidence 文档中的亚马逊 For Oracle](https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-oracle-database/ec2-oracle.html)。 | 数据库管理员 | 
| 创建用于迁移的数据库架构和对象。 | 您可以使用 Amazon Cloud Directory 创建数据库架构。有关更多信息，请参阅 Cloud Directory 文档中的[创建架构](https://docs.aws.amazon.com/clouddirectory/latest/developerguide/getting_started_create_schema.html)。 | 数据库管理员 | 
| 配置入站和出站安全组。 | 要创建和配置安全组，请参阅 Amazon RDS 文档中的[使用安全组控制访问权限](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.RDSSecurityGroups.html)。 | 数据库管理员 | 
| 确认数据库正在运行。 | 要检查数据库的状态，请参阅 Amazon RDS 文档中的[查看 Amazon RDS 事件](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ListEvents.html)。 | 数据库管理员 | 

### 配置 Aurora PostgreSQL 目标数据库
<a name="configure-the-target-aurora-postgresql-database"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 Amazon RDS 中创建 Aurora PostgreSQL 实例。 | 要创建 Aurora PostgreSQL 数据库实例，请参阅 Amazon RDS 文档中的[创建数据库集群并连接到 Aurora PostgreSQL 数据库集群上的数据库](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_GettingStartedAurora.CreatingConnecting.AuroraPostgreSQL.html)。 | 数据库管理员 | 
| 配置入站和出站安全组。 | 要创建和配置安全组，请参阅 Aurora 文档中的[通过创建安全组提供对 VPC 中数据库集群的访问](https://docs.amazonaws.cn/en_us/AmazonRDS/latest/AuroraUserGuide/CHAP_SettingUp_Aurora.html#CHAP_SettingUp_Aurora.SecurityGroup)。 | 数据库管理员 | 
| 确认 Aurora PostgreSQL 数据库正在运行。 | 要检查数据库的状态，请参阅 Aurora 文档中的[查看 Amazon RDS 事件](https://docs.amazonaws.cn/en_us/AmazonRDS/latest/AuroraUserGuide/USER_ListEvents.html)。 | 数据库管理员 | 

### 设置 AWS SCT
<a name="set-up-aws-sct"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 将 AWS SCT 连接到源数据库。 | 要将 AWS SCT 连接到源数据库，请参阅 AWS SCT 文档中的[作为源连接到 PostgreSQL](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Source.PostgreSQL.html#CHAP_Source.PostgreSQL.Connecting)。 | 数据库管理员 | 
| 将 AWS SCT 连接到目标数据库。 | 要将 AWS SCT 连接到目标数据库，请参阅 AWS Schema Conversion Tool 用户指南中的[什么是 AWS Schema Conversion Tool？](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Welcome.html)。 | 数据库管理员 | 
| 在 AWS SCT 中转换数据库架构，并将自动转换后的代码保存为 SQL 文件。 | 要保存 AWS SCT 转换后的文件，请参阅 AWS Schema Conversion Tool 用户指南中的[在 AWS SCT 中保存和应用转换后的架构](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Converting.html#CHAP_Converting.SaveAndApply)。 | 数据库管理员 | 

### 迁移代码
<a name="migrate-the-code"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 获取用于手动转换的 SQL 文件。 | 在 AWS SCT 转换后的文件中，提取需要手动转换的 SQL 文件。 | 数据库管理员 | 
| 更新脚本。 | 手动更新 SQL 文件。 | 数据库管理员 | 

## 相关资源
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-resources"></a>
+ [Amazon RDS](https://aws.amazon.com/rds/)
+ [Amazon Aurora 功能](https://aws.amazon.com/rds/aurora/postgresql-features/)

## 附加信息
<a name="handle-anonymous-blocks-in-dynamic-sql-statements-in-aurora-postgresql-additional"></a>

下面的示例代码显示了如何配置 Oracle 源数据库：

```
CREATE or replace PROCEDURE calc_stats_new1 (
  a NUMBER,
  b NUMBER,
  result out NUMBER)
IS
BEGIN
result:=a+b;
END;
/
```

```
set serveroutput on ;
 
DECLARE
  a NUMBER := 4;
  b NUMBER := 7;
  plsql_block VARCHAR2(100);
  output number;
BEGIN
  plsql_block := 'BEGIN calc_stats_new1(:a, :b,:output); END;';
  EXECUTE IMMEDIATE plsql_block USING a, b,out output;  
  DBMS_OUTPUT.PUT_LINE('output:'||output);
 
END;
```

下面的示例代码显示了如何配置 Aurora PostgreSQL 目标数据库：

```
 w integer,
 x integer)
RETURNS integer
AS
$BODY$
DECLARE
begin
return w + x ;
end;
$BODY$
LANGUAGE  plpgsql;
 
 
CREATE OR REPLACE FUNCTION test_pg.init()
RETURNS void
AS
$BODY$
BEGIN
if aws_oracle_ext.is_package_initialized
      ('test_pg' ) then
      return;
    end if;
    perform aws_oracle_ext.set_package_initialized
      ('test_pg' );
 
PERFORM aws_oracle_ext.set_package_variable('test_pg', 'v_output', NULL::INTEGER);
PERFORM aws_oracle_ext.set_package_variable('test_pg', 'v_status', NULL::text);
END;
$BODY$
LANGUAGE  plpgsql;
 

DO $$ 
declare
v_sql text;
v_output_loc int; 
a integer :=1;
b integer :=2;
BEGIN 
perform  test_pg.init();
--raise notice 'v_sql %',v_sql;
execute 'do $a$ declare v_output_l int; begin select * from test_pg.calc_stats_new1('||a||','||b||') into v_output_l;
PERFORM aws_oracle_ext.set_package_variable(''test_pg'', ''v_output'', v_output_l) ; end; $a$'  ; 
v_output_loc := aws_oracle_ext.get_package_variable('test_pg', 'v_output');
raise notice 'v_output_loc %',v_output_loc; 
END ; 
$$
```