

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

# を使用した Oracle から Amazon RDS for MySQL または Amazon Aurora MySQL への移行 AWS Schema Conversion Tool
<a name="CHAP_Source.Oracle.ToMySQL"></a>

変換した MySQL コードで Oracle データベース関数をエミュレートするには、 AWS SCTで Oracle から MySQL への拡張パックを使用します。拡張機能の詳細については、「[での拡張パックの使用 AWS Schema Conversion Tool](CHAP_ExtensionPack.md)」を参照してください。

**Topics**
+ [MySQL をターゲットデータベースとする場合の権限](#CHAP_Source.Oracle.ToMySQL.ConfigureTarget)
+ [Oracle から MySQL への変換設定](#CHAP_Source.Oracle.ToMySQL.ConversionSettings)
+ [移行に関する考慮事項](#CHAP_Source.Oracle.ToMySQL.MigrationConsiderations)
+ [Oracle の WITH ステートメントから RDS for MySQL または Amazon Aurora MySQL への変換](#CHAP_Source.Oracle.ToMySQL.With)

## MySQL をターゲットデータベースとする場合の権限
<a name="CHAP_Source.Oracle.ToMySQL.ConfigureTarget"></a>

ターゲットとして MySQL に必要な権限を以下に示します。
+ CREATE ON \$1.\$1
+ ALTER ON \$1.\$1
+ DROP ON \$1.\$1
+ INDEX ON \$1.\$1
+ REFERENCES ON \$1.\$1
+ SELECT ON \$1.\$1
+ CREATE VIEW ON \$1.\$1
+ SHOW VIEW ON \$1.\$1
+ TRIGGER ON \$1.\$1
+ CREATE ROUTINE ON \$1.\$1
+ ALTER ROUTINE ON \$1.\$1
+ EXECUTE ON \$1.\$1
+ CREATE TEMPORARY TABLES ON \$1.\$1
+ AWS\$1LAMBDA\$1ACCESS
+ INSERT, UPDATE ON AWS\$1ORACLE\$1EXT.\$1
+ INSERT, UPDATE, DELETE ON AWS\$1ORACLE\$1EXT\$1DATA.\$1

バージョン 5.7 以前の MySQL データベースをターゲットとして使用する場合は、AWS\$1LAMBDA\$1ACCESS の代わりに INVOKE LAMBDA \$1.\$1 権限を付与します。MySQL データベースバージョン 8.0 以降の場合は、AWS\$1LAMBDA\$1ACCESS 権限を付与します。

次のコード例を使用してデータベースユーザーを作成し、権限を付与できます。

```
CREATE USER 'user_name' IDENTIFIED BY 'your_password';
GRANT CREATE ON *.* TO 'user_name';
GRANT ALTER ON *.* TO 'user_name';
GRANT DROP ON *.* TO 'user_name';
GRANT INDEX ON *.* TO 'user_name';
GRANT REFERENCES ON *.* TO 'user_name';
GRANT SELECT ON *.* TO 'user_name';
GRANT CREATE VIEW ON *.* TO 'user_name';
GRANT SHOW VIEW ON *.* TO 'user_name';
GRANT TRIGGER ON *.* TO 'user_name';
GRANT CREATE ROUTINE ON *.* TO 'user_name';
GRANT ALTER ROUTINE ON *.* TO 'user_name';
GRANT EXECUTE ON *.* TO 'user_name';
GRANT CREATE TEMPORARY TABLES ON *.* TO 'user_name';
GRANT AWS_LAMBDA_ACCESS TO 'user_name';
GRANT INSERT, UPDATE ON AWS_ORACLE_EXT.* TO 'user_name';
GRANT INSERT, UPDATE, DELETE ON AWS_ORACLE_EXT_DATA.* TO 'user_name';
```

前述の例では、[*user\$1name*] をお客様の設定のユーザー名に置き換えます。*your\$1password* を安全なパスワードに置き換えます。

バージョン 5.7 以前の MySQL データベースをターゲットとして使用する場合は、`GRANT AWS_LAMBDA_ACCESS TO 'user_name'` の代わりに `GRANT INVOKE LAMBDA ON *.* TO 'user_name'` を使用してください。

Amazon RDS for MySQL または Aurora MySQL をターゲットとして使用するには、`lower_case_table_names` パラメータを `1` に設定します。この値は、MySQL サーバーがテーブル、インデックス、トリガー、データベースなどのオブジェクト名の識別子を、大文字と小文字を区別せずに処理することを意味します。ターゲットインスタンスでバイナリログを有効にしている場合は、`log_bin_trust_function_creators` パラメータを `1` と設定します。この場合、ストアド関数を作成するのに、`DETERMINISTIC` 特性、`READS SQL DATA` 特性、`NO SQL` 特性を使用する必要はありません。これらのパラメータを設定するには、新しい DB パラメータグループを作成するか、既存の DB パラメータグループを変更します。

## Oracle から MySQL への変換設定
<a name="CHAP_Source.Oracle.ToMySQL.ConversionSettings"></a>

Oracle から MySQL への変換設定を編集するには、「 **の設定**」を選択し AWS SCT、**「変換設定**」を選択します。上部のリストから **Oracle** を選択し、**Oracle – MySQL** を選択します。Oracle から MySQL への変換に使用できるすべての設定 AWS SCT が表示されます。

の Oracle から MySQL への変換設定には、以下のオプション AWS SCT が含まれています。
+ 変換されたコード内のアクション項目に関するコメントの数を制限する。

  選択した**重要度以上のアクション項目の変換されたコードにコメントを追加する で**、アクション項目の重要度を選択します。 は、選択した重要度以上のアクション項目の変換されたコードにコメント AWS SCT を追加します。

  たとえば、変換したコード内のコメントの数を最小限に抑えるには、[**エラーのみ**] を選択します。変換したコードのすべてのアクション項目にコメントを含めるには、[**すべてのメッセージ**] を選択します。
+ ソース Oracle データベースが擬似列を使用できるが、MySQL `ROWID` は同様の機能をサポートしていないことに対応するために、 は変換されたコードで`ROWID`擬似列をエミュレート AWS SCT できます。そのためには、[**行 ID を生成しますか**] で [**ID として生成**] を選択します。

  Oracle のソースコードで `ROWID` 疑似列を使用していない場合は、[**行 ID を生成しますか**] で [**生成しない**] を選択します。この場合、変換されたコードの処理が速くなります。
+ MySQL がサポートしていないパラメータを持つ`TO_CHAR`、`TO_DATE`、`TO_NUMBER` 関数が含まれているソースの Oracle コードを操作する。デフォルトでは、 AWS SCT は変換後のコードでこれらのパラメータの使用法をエミュレートします。

  ソース Oracle コードに PostgreSQL がサポートするパラメータのみが含まれている場合は、ネイティブの MySQL `TO_CHAR`、`TO_DATE`、`TO_NUMBER` 関数を使用できます。この場合、変換されたコードの処理が速くなります。これらのパラメータのみを含めるには、以下の値を選択します。
  + **関数 TO\$1CHAR () は Oracle 固有のフォーマット文字列を使用しません。**
  + **関数 TO\$1DATE () は Oracle 固有のフォーマット文字列を使用しません**
  + **関数 TO\$1NUMBER () は Oracle 固有のフォーマット文字列を使用しません**
+ データベースとアプリケーションが異なるタイムゾーンで実行されているかどうかを調べる。デフォルトでは、 AWS SCT は変換されたコードのタイムゾーンをエミュレートします。ただし、データベースとアプリケーションが同じタイムゾーンを使用している場合は、このエミュレーションは必要ありません。この場合、[**クライアント側のタイムゾーンをサーバーのタイムゾーンと一致させる**] を選択してください。

## 移行に関する考慮事項
<a name="CHAP_Source.Oracle.ToMySQL.MigrationConsiderations"></a>

Oracle を RDS for MySQL または Aurora MySQL に変換する場合、ステートメントの実行順序を変更するには、`GOTO` ステートメントとラベルを使用できます。GOTO ステートメントに続くすべての `GOTO` ステートメントはスキップされ、ラベルで処理が継続されます。`GOTO` ステートメントとラベルは、プロシージャ、バッチ、またはステートメント ブロック内のどこでも使用できます。GOTO ステートメントをネストすることもできます。

MySQL は `GOTO` ステートメントを使用しません。は、 `GOTO`ステートメントを含むコードを AWS SCT 変換すると、 ステートメントを `BEGIN…END`または `LOOP…END LOOP`ステートメントを使用するように変換します。

が`GOTO`ステートメントを AWS SCT 変換する方法の例を次の表に示します。


| Oracle ステートメント | MySQL ステートメント | 
| --- | --- | 
|  <pre>BEGIN<br />   ....<br />   statement1;<br />   ....<br />   GOTO label1;<br />   statement2;<br />   ....<br />   label1:<br />   Statement3;<br />   ....<br />END<br /></pre>  |  <pre>BEGIN<br /> label1:<br /> BEGIN<br />   ....<br />   statement1;<br />   ....<br />   LEAVE label1;<br />   statement2;<br />   ....<br /> END;<br />   Statement3;<br />   ....<br />END<br /></pre>  | 
|  <pre>BEGIN<br />   ....<br />   statement1;<br />   ....<br />   label1:<br />   statement2;<br />   ....<br />   GOTO label1;<br />   statement3;<br />   ....<br />   statement4;<br />   ....<br />END<br /></pre>  |  <pre>BEGIN<br />   ....<br />   statement1;<br />   ....<br />   label1:<br />   LOOP<br />    statement2;<br />    ....<br />    ITERATE label1;<br />    LEAVE label1;<br />   END LOOP; <br />    statement3;<br />    ....<br />    statement4;<br />    ....<br />END<br /></pre>  | 
|  <pre>BEGIN<br />   ....<br />   statement1;<br />   ....<br />   label1:<br />   statement2;<br />   ....<br />   statement3;<br />   ....<br />   statement4;<br />   ....<br />END<br /></pre>  |  <pre>BEGIN<br />   ....<br />   statement1;<br />   ....<br />   label1:<br />   BEGIN<br />    statement2;<br />    ....    <br />    statement3;<br />    ....<br />    statement4;<br />    ....    <br />   END; <br />END<br /></pre>  | 

## Oracle の WITH ステートメントから RDS for MySQL または Amazon Aurora MySQL への変換
<a name="CHAP_Source.Oracle.ToMySQL.With"></a>

名前 (query\$1name) をサブクエリのブロックに割り当てるには、WITH 句 (subquery\$1factoring) を Oracle で使用します。サブクエリブロックをクエリの複数の場所で参照するには、query\$1name を指定します。サブクエリブロックにリンクまたはパラメータ (ローカル、プロシージャ、関数、パッケージ) が含まれていない場合、 は 句をビューまたは一時テーブル AWS SCT に変換します。

句を一時テーブルに変換する利点は、サブクエリへの繰り返し参照がより効率的であることです。各参照によって要求されるのではなく、一時テーブルからデータが簡単に取得されるために効率が向上します。追加のビューまたは一時テーブルを使用して、これをエミュレートできます。ビュー名には `<procedure_name>$<subselect_alias>` の形式が使用されます。

次の表で例を確認できます。


| Oracle ステートメント | MySQL ステートメント | 
| --- | --- | 
|  <pre>CREATE PROCEDURE <br /> TEST_ORA_PG.P_WITH_SELECT_VARIABLE_01<br />     (p_state IN NUMBER)<br />AS<br />  l_dept_id NUMBER := 1; <br />BEGIN<br />FOR cur IN  <br />           (WITH dept_empl(id, name, surname, <br />              lastname, state, dept_id)<br />              AS<br />                  (<br />                    SELECT id, name, surname,  <br />                     lastname, state, dept_id <br />                      FROM test_ora_pg.dept_employees<br />                     WHERE state = p_state AND <br />                       dept_id = l_dept_id)<br />            SELECT id,state   <br />              FROM dept_empl<br />            ORDER BY id)  LOOP<br />  NULL;<br />END LOOP;<br /></pre>  |  <pre>CREATE PROCEDURE test_ora_pg.P_WITH_SELECT_VARIABLE_01(IN par_P_STATE DOUBLE)<br />BEGIN<br />    DECLARE var_l_dept_id DOUBLE DEFAULT 1;<br />    DECLARE var$id VARCHAR (8000);<br />    DECLARE var$state VARCHAR (8000);<br />    DECLARE done INT DEFAULT FALSE;<br />    DECLARE cur CURSOR FOR SELECT<br />        ID, STATE<br />        FROM (SELECT<br />            ID, NAME, SURNAME, LASTNAME, STATE, DEPT_ID<br />            FROM TEST_ORA_PG.DEPT_EMPLOYEES<br />            WHERE STATE = par_p_state AND DEPT_ID = var_l_dept_id) AS dept_empl<br />        ORDER BY ID;<br />    DECLARE CONTINUE HANDLER FOR NOT FOUND<br />        SET done := TRUE;<br />    OPEN cur;<br /><br />    read_label:<br />    LOOP<br />        FETCH cur INTO var$id, var$state;<br /><br />        IF done THEN<br />            LEAVE read_label;<br />        END IF;<br /><br />        BEGIN<br />        END;<br />    END LOOP;<br />    CLOSE cur;<br />END;<br /></pre>  | 
|  <pre>CREATE PROCEDURE <br /> TEST_ORA_PG.P_WITH_SELECT_REGULAR_MULT_01<br />AS    <br />BEGIN<br /><br /> FOR cur IN  (<br />               WITH dept_empl AS<br />                   (<br />                        SELECT id, name, surname, <br />                         lastname, state, dept_id <br />                          FROM test_ora_pg.dept_employees<br />                         WHERE state = 1),<br />                    dept AS <br />                   (SELECT id deptid, parent_id, <br />                      name deptname<br />                      FROM test_ora_pg.department                <br />                   )<br />                SELECT dept_empl.*,dept.*          <br />                 FROM dept_empl, dept<br />                 WHERE dept_empl.dept_id = dept.deptid<br />              ) LOOP<br />              NULL;<br />            END LOOP;<br /></pre>  |  <pre>CREATE VIEW TEST_ORA_PG.`P_WITH_SELECT_REGULAR_MULT_01$dept_empl<br /> `(id, name, surname, lastname, state, dept_id)<br />AS<br />(SELECT id, name, surname, lastname, state, dept_id <br />   FROM test_ora_pg.dept_employees<br />  WHERE state = 1);<br />  <br />CREATE VIEW TEST_ORA_PG.`P_WITH_SELECT_REGULAR_MULT_01$dept<br /> `(deptid, parent_id,deptname)<br />AS<br />(SELECT id deptid, parent_id, name deptname<br />   FROM test_ora_pg.department);  <br /><br /><br />CREATE PROCEDURE test_ora_pg.P_WITH_SELECT_REGULAR_MULT_01()<br />BEGIN<br />    DECLARE var$ID DOUBLE;<br />    DECLARE var$NAME VARCHAR (30);<br />    DECLARE var$SURNAME VARCHAR (30);<br />    DECLARE var$LASTNAME VARCHAR (30);<br />    DECLARE var$STATE DOUBLE;<br />    DECLARE var$DEPT_ID DOUBLE;<br />    DECLARE var$deptid DOUBLE;<br />    DECLARE var$PARENT_ID DOUBLE;<br />    DECLARE var$deptname VARCHAR (200);<br />    DECLARE done INT DEFAULT FALSE;<br />    DECLARE cur CURSOR FOR SELECT<br />        dept_empl.*, dept.*<br />        FROM TEST_ORA_PG.`P_WITH_SELECT_REGULAR_MULT_01$dept_empl<br />          ` AS dept_empl,<br />             TEST_ORA_PG.`P_WITH_SELECT_REGULAR_MULT_01$dept<br />          ` AS dept<br />        WHERE dept_empl.DEPT_ID = dept.DEPTID;<br />    DECLARE CONTINUE HANDLER FOR NOT FOUND<br />        SET done := TRUE;<br />    OPEN cur;<br /><br />    read_label:<br />    LOOP<br />    FETCH cur INTO var$ID, var$NAME, var$SURNAME, <br />     var$LASTNAME, var$STATE, var$DEPT_ID, var$deptid, <br />     var$PARENT_ID, var$deptname;<br /><br />        IF done THEN<br />            LEAVE read_label;<br />        END IF;<br /><br />        BEGIN<br />        END;<br />    END LOOP;<br />    CLOSE cur;<br />END;<br /><br />call test_ora_pg.P_WITH_SELECT_REGULAR_MULT_01()<br /></pre>  | 
|  <pre>CREATE PROCEDURE <br />  TEST_ORA_PG.P_WITH_SELECT_VAR_CROSS_02(p_state IN NUMBER)<br />AS    <br />   l_dept_id NUMBER := 10;<br />BEGIN<br /> FOR cur IN  (<br />               WITH emp AS              <br />                    (SELECT id, name, surname, <br />                      lastname, state, dept_id <br />                       FROM test_ora_pg.dept_employees<br />                      WHERE dept_id > 10                 <br />                    ),<br />                    active_emp AS<br />                    (<br />                      SELECT id<br />                        FROM emp<br />                       WHERE emp.state = p_state <br />                    )<br />                    <br />                SELECT *          <br />                  FROM active_emp                 <br />              ) LOOP<br />         NULL;<br />  END LOOP;<br />  <br />END;<br /></pre>  |  <pre>CREATE VIEW TEST_ORA_PG.`P_WITH_SELECT_VAR_CROSS_01$emp<br />    `(id, name, surname, lastname, state, dept_id)<br />AS<br />(SELECT<br />       id, name, surname, lastname, <br />       state, dept_id<br />  FROM TEST_ORA_PG.DEPT_EMPLOYEES<br />  WHERE DEPT_ID > 10);<br /><br /><br />CREATE PROCEDURE <br />   test_ora_pg.P_WITH_SELECT_VAR_CROSS_02(IN par_P_STATE DOUBLE)<br />BEGIN<br />    DECLARE var_l_dept_id DOUBLE DEFAULT 10;<br />    DECLARE var$ID DOUBLE;<br />    DECLARE done INT DEFAULT FALSE;<br />    DECLARE cur CURSOR FOR SELECT *<br />                             FROM (SELECT<br />                                      ID<br />                                     FROM <br />                             TEST_ORA_PG.<br />                              `P_WITH_SELECT_VAR_CROSS_01$emp` AS emp<br />                                   WHERE emp.STATE = par_p_state) <br />                                    AS active_emp;<br />    DECLARE CONTINUE HANDLER FOR NOT FOUND<br />        SET done := TRUE;<br />    OPEN cur;<br /><br />    read_label:<br />    LOOP<br />        FETCH cur INTO var$ID;<br /><br />        IF done THEN<br />            LEAVE read_label;<br />        END IF;<br /><br />        BEGIN<br />        END;<br />    END LOOP;<br />    CLOSE cur;<br />END;<br /></pre>  | 