

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# レガシーアプリケーションを Oracle Pro\*C から ECPG に移行する
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg"></a>

*Amazon Web Services、Sai Parthasaradhi、Mahesh Balumuri*

## 概要
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-summary"></a>

SQL コードが埋め込まれているほとんどのレガシーアプリケーションは、Oracle Pro\*C プリコンパイラを使用してデータベースにアクセスします。これらの Oracle データベースを PostgreSQL 用の Amazon Relational Database Service (Amazon RDS) または Amazon Aurora PostgreSQL-Compatible エディションに移行する場合、アプリケーションコードを PostgreSQL のプリコンパイラと互換性のある形式 (ECPG と呼ばれる) に変換する必要があります。このパターンは、Oracle Pro\*C のコードを PostgreSQL ECPG の同等のコードに変換する方法を説明しています。 

Pro\*C の詳細については、[Oracle のドキュメント](https://docs.oracle.com/cd/E11882_01/appdev.112/e10825/pc_01int.htm#i2415)を参照してください。ECPG の簡単な紹介については、「[追加情報](#migrate-legacy-applications-from-oracle-pro-c-to-ecpg-additional)」セクションを参照してください。

## 前提条件と制限事項
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ Amazon RDS for PostgreSQL または Aurora PostgreSQL-Compatible データベース
+ オンプレミスで稼働している Oracle データベース

## ツール
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-tools"></a>
+ 次のセクションにリストされている PostgreSQL パッケージ。
+ [ CLI ](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) - AWS コマンドラインインターフェイス (AWS CLI) はオープンソースのツールで、コマンドラインシェルのコマンドで AWS サービスとインタラクトします。最小限の構成で、コマンドプロンプトからブラウザベースの AWS マネジメントコンソールで提供される機能と同等の機能を実装する AWS CLI コマンドを実行できます。

## エピック
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-epics"></a>

### CentOS または RHEL でビルド環境を設定する
<a name="set-the-build-environment-on-centos-or-rhel"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| PostgreSQL パッケージをインストールします。 | 次のコマンドを使用して必要な PostgreSQL パッケージをインストールします。<pre>yum update -y<br />yum install -y yum-utils<br />rpm -ivh https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm<br />dnf -qy module disable postgresql</pre> | アプリ開発者、DevOps エンジニア | 
| ヘッダーファイルとライブラリをインストールします。 | 以下のコマンドを使用して、ヘッダーファイルとライブラリを含む `postgresql12-devel` パッケージをインストールします。ランタイム環境でのエラーを避けるため、開発環境とランタイム環境の両方にパッケージをインストールします。<pre>dnf -y install postgresql12-devel<br />yum install ncompress zip ghostscript jq unzip wget git -y</pre><br />開発環境でのみ、次のコマンドも実行します。<pre>yum install zlib-devel make -y<br />ln -s /usr/pgsql-12/bin/ecpg /usr/bin/</pre> | アプリ開発者、DevOps エンジニア | 
| 環境変数のパスを構成します。 | PostgreSQL クライアントライブラリの環境パスを設定します。<pre>export PATH=$PATH:/usr/pgsql-12/bin</pre> | アプリ開発者、DevOps エンジニア | 
| 必要に応じて追加のソフトウェアをインストールします。 | 必要に応じて、Oracle の **SQL\*Loader** の代わりに **pgLoader** をインストールしてください。<pre>wget -O /etc/yum.repos.d/pgloader-ccl.repo https://dl.packager.io/srv/opf/pgloader-ccl/master/installer/el/7.repo<br />yum install pgloader-ccl -y<br />ln -s /opt/pgloader-ccl/bin/pgloader /usr/bin/</pre><br />Pro\*C モジュールから Java アプリケーションを呼び出す場合は、Java をインストールしてください。<pre>yum install java -y</pre><br />**ant** をインストールして Java コードをコンパイルします。<pre>yum install ant -y</pre> | アプリ開発者、DevOps エンジニア | 
| AWS CLI をインストールします。 | AWS CLI をインストールして、アプリケーションから AWS Secrets Manager や Amazon Simple Storage Service (Amazon S3) などの AWS のサービスと対話するコマンドを実行します。<pre>cd /tmp/<br />curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"<br />unzip awscliv2.zip<br />./aws/install -i /usr/local/aws-cli -b /usr/local/bin --update</pre> | アプリ開発者、DevOps エンジニア | 
| 変換するプログラムを特定します。 | Pro\*C から ECPG に変換するアプリケーションを特定します。 | アプリ開発者、アプリオーナー | 

### Pro\*C コードを ECPG に変換する
<a name="convert-pro-c-code-to-ecpg"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 不要なヘッダーを削除する。 | PostgreSQL では不要な `include ` ヘッダーを削除します。例えば、`oci.h`、`oratypes`、および `sqlda` など。 | アプリ所有者、アプリ開発者 | 
| 変数宣言を更新します。 | ホスト変数として使用されるすべての変数宣言に `EXEC SQL` ステートメントを追加します。<br />次のような `EXEC SQL VAR` 宣言をアプリケーションから削除します。<pre>EXEC SQL VAR query IS STRING(2048);</pre> | アプリ開発者、アプリオーナー | 
| ROWNUM 機能を更新します。 | `ROWNUM` 関数は PostgreSQL では使用できません。これを SQL クエリの `ROW_NUMBER` ウィンドウ関数に置き換えてください。<br />Pro\*C コード:<pre>SELECT SUBSTR(RTRIM(FILE_NAME,'.txt'),12) INTO :gcpclFileseq  <br />FROM   (SELECT FILE_NAME <br />FROM  DEMO_FILES_TABLE <br />WHERE FILE_NAME    LIKE '%POC%' <br />ORDER BY FILE_NAME DESC) FL2 <br />WHERE ROWNUM <=1 ORDER BY ROWNUM;</pre><br />ECPG コード:<pre>SELECT SUBSTR(RTRIM(FILE_NAME,'.txt'),12) INTO :gcpclFileseq  <br />FROM   (SELECT FILE_NAME , ROW_NUMBER() OVER (ORDER BY FILE_NAME DESC) AS ROWNUM<br />FROM  demo_schema.DEMO_FILES_TABLE <br />WHERE FILE_NAME    LIKE '%POC%'<br />ORDER BY FILE_NAME DESC) FL2 <br />WHERE ROWNUM <=1 ORDER BY ROWNUM; </pre> | アプリ開発者、アプリオーナー | 
| エイリアス変数を使用するように関数パラメータを更新します。 | PostgreSQL では、関数パラメータをホスト変数として使用することはできません。エイリアス変数を使用してそれらを上書きします。<br />Pro\*C コード:<pre>int processData(int referenceId){<br />  EXEC SQL char col_val[100];<br />  EXEC SQL select column_name INTO :col_val from table_name where col=:referenceId;<br />}</pre><br />ECPG コード:<pre>int processData(int referenceIdParam){<br />  EXEC SQL int referenceId = referenceIdParam;<br />  EXEC SQL char col_val[100];<br />  EXEC SQL select column_name INTO :col_val from table_name where col=:referenceId;<br />}</pre> | アプリ開発者、アプリオーナー | 
| 構造体タイプを更新します。 | `struct` 型変数がホスト変数として使用される場合は、`EXEC SQL BEGIN` および `END` ブロックの `struct` 型を `typedef` で定義します。`struct` 型がヘッダー (`.h`) ファイルで定義されている場合は、`EXEC SQL` include ステートメントでファイルをインクルードします。<br />Pro\*C コード:<br />ヘッダーファイル (`demo.h`)<pre>struct s_partition_ranges<br />{<br /> char   sc_table_group[31];<br /> char   sc_table_name[31];<br /> char   sc_range_value[10];<br />}; <br />struct s_partition_ranges_ind<br />{<br />  short    ss_table_group;<br />  short    ss_table_name;<br />  short    ss_range_value;<br />}; </pre><br />ECPG コード:<br />ヘッダーファイル (`demo.h`)<pre>EXEC SQL BEGIN DECLARE SECTION;<br />typedef struct <br />{<br />  char   sc_table_group[31];<br />  char   sc_table_name[31];<br />  char   sc_range_value[10];<br />} s_partition_ranges; <br />typedef struct <br />{<br />  short    ss_table_group;<br />  short    ss_table_name;<br />  short    ss_range_value;<br />} s_partition_ranges_ind; <br />EXEC SQL END DECLARE SECTION;</pre><br />Pro\*C ファイル (`demo.pc`) <pre>#include "demo.h"<br />struct s_partition_ranges gc_partition_data[MAX_PART_TABLE] ;<br />struct s_partition_ranges_ind gc_partition_data_ind[MAX_PART_TABLE] ;</pre><br />ECPG ファイル (`demo.pc`) <pre>exec sql include "demo.h"<br />EXEC SQL BEGIN DECLARE SECTION;<br />s_partition_ranges gc_partition_data[MAX_PART_TABLE] ;<br />s_partition_ranges_ind gc_partition_data_ind[MAX_PART_TABLE] ;<br />EXEC SQL END DECLARE SECTION;</pre> | アプリ開発者、アプリオーナー | 
| カーソルから取得するようにロジックを変更します。 | 配列変数を使用してカーソルから複数の行を取得するには、`FETCH FORWARD` を使用するようコードを変更します。<br />Pro\*C コード:<pre>EXEC SQL char  aPoeFiles[MAX_FILES][FILENAME_LENGTH];<br />EXEC SQL FETCH filename_cursor into :aPoeFiles;</pre><br />ECPG コード:<pre>EXEC SQL char  aPoeFiles[MAX_FILES][FILENAME_LENGTH];<br />EXEC SQL int fetchSize = MAX_FILES;<br />EXEC SQL FETCH FORWARD :fetchSize filename_cursor into :aPoeFiles;</pre> | アプリ開発者、アプリオーナー | 
| 戻り値がないパッケージコールを修正します。 | 戻り値のない Oracle パッケージ関数は、指標変数を使用して呼び出す必要があります。アプリケーションに同じ名前の関数が複数含まれている場合や、型が不明な関数がランタイムエラーを生成する場合は、値をデータ型に typecast します。<br />Pro\*C コード:<pre>void ProcessData (char *data , int id)<br />{        <br />        EXEC SQL EXECUTE<br />               BEGIN<br />                  pkg_demo.process_data (:data, :id);                                                                                    <br />               END;<br />       END-EXEC;<br />}</pre><br />ECPG コード:<pre>void ProcessData (char *dataParam, int idParam )<br />{<br />        EXEC SQL char *data = dataParam;<br />        EXEC SQL int id = idParam;<br />        EXEC SQL short rowInd;<br />        EXEC SQL short rowInd = 0;<br />        EXEC SQL SELECT pkg_demo.process_data (<br />                       inp_data => :data::text,<br />                       inp_id => :id<br />               ) INTO :rowInd;<br />}</pre> | アプリ開発者、アプリオーナー | 
| SQL\_CURSOR 変数を書き換える。 | `SQL_CURSOR` 変数とその実装を書き直します。<br />Pro\*C コード:<pre>/* SQL Cursor */<br />SQL_CURSOR      demo_cursor;<br />EXEC SQL ALLOCATE :demo_cursor;<br />EXEC SQL EXECUTE<br />  BEGIN<br />      pkg_demo.get_cursor(     <br />        demo_cur=>:demo_cursor<br />      );<br />  END;<br />END-EXEC;</pre><br />ECPG コード:<pre>EXEC SQL DECLARE demo_cursor CURSOR FOR SELECT<br />         * from<br />    pkg_demo.open_filename_rc(<br />            demo_cur=>refcursor<br />          ) ;<br />EXEC SQL char open_filename_rcInd[100]; <br /># As the below function returns cursor_name as <br /># return we need to use char[] type as indicator. <br />EXEC SQL SELECT pkg_demo.get_cursor (<br />        demo_cur=>'demo_cursor'<br />    ) INTO :open_filename_rcInd;</pre> | アプリ開発者、アプリオーナー | 
| 一般的な移行パターンを適用します。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/migrate-legacy-applications-from-oracle-pro-c-to-ecpg.html) | アプリ開発者、アプリオーナー | 
| 必要に応じてデバッグを有効にします。 | ECPG プログラムをデバッグモードで実行するには、メイン関数ブロック内に以下のコマンドを追加します。<pre>ECPGdebug(1, stderr); </pre> | アプリ開発者、アプリオーナー | 

### ECPG プログラムをコンパイルする
<a name="compile-ecpg-programs"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ECPG 用の実行ファイルを作成します。 | `prog1.pgc` という名前の埋め込み SQL C ソースファイルがある場合は、以下のコマンドシーケンスを使用して実行プログラムを作成できます。<pre>ecpg prog1.pgc<br />cc -I/usr/local/pgsql/include -c prog1.c<br />cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg</pre> | アプリ開発者、アプリオーナー | 
| コンパイル用の Make ファイルを作成します。 | 次のサンプルファイルに示されているように、ECPG プログラムをコンパイルする Make ファイルを作成します。<pre>CFLAGS ::= $(CFLAGS) -I/usr/pgsql-12/include -g -Wall<br />LDFLAGS ::= $(LDFLAGS) -L/usr/pgsql-12/lib -Wl,-rpath,/usr/pgsql-12/lib<br />LDLIBS ::= $(LDLIBS) -lecpg<br />PROGRAMS = test <br />.PHONY: all clean<br />%.c: %.pgc<br />      ecpg $<<br />all: $(PROGRAMS)<br />clean:<br />    rm -f $(PROGRAMS) $(PROGRAMS:%=%.c) $(PROGRAMS:%=%.o)</pre> | アプリ開発者、アプリオーナー | 

### アプリケーションをテストする
<a name="test-the-application"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| コードをテストします。 | 変換したアプリケーションコードをテストして、正しく機能することを確認します。 | アプリ開発者、アプリオーナー、テストエンジニア | 

## 関連リソース
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-resources"></a>
+ [ECPG - C で記述された埋め込み SQL](https://www.postgresql.org/docs/current/static/ecpg.html) (PostgreSQL ドキュメント)
+ [エラーの処理](https://www.postgresql.org/docs/12/ecpg-errors.html) (PostgreSQL ドキュメント)
+ [Oracle Pro\*C/C\+\+ プリコンパイラを使用する理由](https://docs.oracle.com/cd/E11882_01/appdev.112/e10825/pc_01int.htm#i2415) (Oracle ドキュメント)

## 追加情報
<a name="migrate-legacy-applications-from-oracle-pro-c-to-ecpg-additional"></a>

PostgreSQL には、Oracle Pro\*C プリコンパイラと同等の埋め込み SQL プリコンパイラ ECPG があります。ECPG は、SQL コールを特殊な関数の呼び出しに置き換えることで、埋め込み SQL 文を含む C プログラムを標準 C コードに変換します。その後、出力ファイルは任意の C コンパイラツールチェーンで処理できます。

**入力ファイルと出力ファイル**

ECPG は、コマンドラインで指定した各入力ファイルを対応する C 出力ファイルに変換します。入力ファイル名にファイル拡張子が付いていない場合は、.pgc とみなされます。ファイルの拡張子は `.c` に置き換えられ、出力ファイル名が作成されます。ただし、`-o` オプションでデフォルトの出力ファイル名をオーバーライドできます。

入力ファイル名としてダッシュ (`-`) を使用すると、ECPG は `-o` オプションを使用してプログラムをオーバーライドしない限り、標準入力からプログラムを読み取り、標準出力に書き込みます。

**ヘッダーファイル**

PostgreSQL コンパイラは、前処理された C コードファイルをコンパイルするときに、PostgreSQL `include`ディレクトリ内の ECPG ヘッダーファイルを探します。そのため、`-I` オプションを使用してコンパイラに正しいディレクトリ (例: `-I/usr/local/pgsql/include`) を指定しなければならない場合があります。

**[ライブラリ]**

埋め込み SQL で C コードを使用するプログラムは、`libecpg` ライブラリにリンクする必要があります。例えば、リンカーオプション ` -L/usr/local/pgsql/lib -lecpg` を使用できます。

変換されたECPGアプリケーションは、埋め込み SQL ライブラリ (`ecpglib`) を介して `libpq` ライブラリ内の関数を呼び出し、標準のフロントエンド/バックエンドプロトコルを使用して PostgreSQL サーバーと通信します。