

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Migration d'Oracle vers Amazon RDS for MySQL ou Amazon Aurora MySQL avec AWS Schema Conversion Tool
<a name="CHAP_Source.Oracle.ToMySQL"></a>

Pour émuler les fonctions de base de données Oracle dans votre code MySQL converti, utilisez le pack d'extension Oracle to MySQL dans AWS SCT. Pour plus d’informations sur les packs d’extension, consultez [Utilisation de packs d'extension avec AWS Schema Conversion Tool](CHAP_ExtensionPack.md). 

**Topics**
+ [Privilèges pour MySQL en tant que base de données cible](#CHAP_Source.Oracle.ToMySQL.ConfigureTarget)
+ [Paramètres de conversion Oracle vers MySQL](#CHAP_Source.Oracle.ToMySQL.ConversionSettings)
+ [Considérations concernant la migration](#CHAP_Source.Oracle.ToMySQL.MigrationConsiderations)
+ [Conversion de l'instruction WITH dans Oracle en RDS pour MySQL ou Amazon Aurora MySQL](#CHAP_Source.Oracle.ToMySQL.With)

## Privilèges pour MySQL en tant que base de données cible
<a name="CHAP_Source.Oracle.ToMySQL.ConfigureTarget"></a>

Les privilèges requis pour MySQL en tant que cible sont les suivants :
+ CRÉER SUR\$1 . \$1
+ MODIFIER \$1 . \$1
+ DÉPOSEZ \$1 . \$1
+ INDEX SUR \$1 . \$1
+ RÉFÉRENCES SUR\$1 . \$1
+ SELECT ON \$1.\$1
+ CRÉER UNE VUE SUR \$1 . \$1
+ SHOW VIEW ON \$1.\$1
+ DÉCLENCHEUR ACTIVÉ\$1 . \$1
+ CRÉER UNE ROUTINE SUR\$1 . \$1
+ MODIFIER LA ROUTINE SUR \$1 . \$1
+ EXÉCUTER SUR\$1 . \$1
+ CRÉER DES TABLES TEMPORAIRES SUR\$1 . \$1
+ AWS\$1LAMBDA\$1ACCÈS
+ INSÉRER, METTRE À JOUR SUR AWS\$1ORACLE \$1EXT. \$1
+ INSÉREZ, METTEZ À JOUR, SUPPRIMEZ SUR AWS\$1ORACLE \$1EXT\$1DATA. \$1

Si vous utilisez une base de données MySQL version 5.7 ou inférieure comme cible, accordez l'autorisation INVOKE LAMBDA \$1.\$1 au lieu de AWS\$1LAMBDA \$1ACCESS. Pour les bases de données MySQL version 8.0 et supérieures, accordez l' AWS\$1LAMBDA\$1ACCESS autorisation.

Vous pouvez utiliser l’exemple de code suivant pour créer un utilisateur de base de données et accorder les privilèges.

```
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';
```

Dans l'exemple précédent, remplacez *user\$1name* par le nom de votre utilisateur. Remplacez-le ensuite *your\$1password* par un mot de passe sécurisé.

Si vous utilisez une base de données MySQL version 5.7 ou inférieure comme cible, utilisez `GRANT INVOKE LAMBDA ON *.* TO 'user_name'` plutôt que`GRANT AWS_LAMBDA_ACCESS TO 'user_name'`.

Pour utiliser Amazon RDS for MySQL ou Aurora MySQL en tant que cible, définissez le paramètre `lower_case_table_names` sur `1`. Cette valeur signifie que le serveur MySQL traite les identifiants des noms d’objets tels que les tables, les index, les déclencheurs et les bases de données sans distinction entre majuscules et minuscules. Si vous avez activé la journalisation binaire dans votre instance cible, définissez le paramètre `log_bin_trust_function_creators` sur `1`. Dans ce cas, vous n’avez pas besoin d’utiliser les caractéristiques `DETERMINISTIC`, `READS SQL DATA` ni `NO SQL` pour créer des fonctions stockées. Pour configurer ces paramètres, créez un nouveau groupe de paramètres de base de données ou modifiez un groupe de paramètres de base de données existant.

## Paramètres de conversion Oracle vers MySQL
<a name="CHAP_Source.Oracle.ToMySQL.ConversionSettings"></a>

Pour modifier les paramètres de conversion d'Oracle vers MySQL, choisissez **Paramètres** dans AWS SCT, puis sélectionnez **Paramètres de conversion**. Dans la liste supérieure, choisissez **Oracle**, puis **Oracle — MySQL**. AWS SCT affiche tous les paramètres disponibles pour la conversion d'Oracle vers MySQL.

Les paramètres de conversion d'Oracle vers MySQL AWS SCT incluent des options pour les éléments suivants :
+ Pour limiter le nombre de commentaires contenant des actions dans le code converti.

  Pour **Ajouter des commentaires dans le code converti pour les actions de gravité sélectionnée ou supérieure**, choisissez la sévérité des actions. AWS SCT ajoute des commentaires dans le code converti pour les actions dont la sévérité est sélectionnée ou supérieure.

  Par exemple, pour réduire au maximum le nombre de commentaires dans votre code converti, choisissez **Erreurs uniquement**. Pour inclure les commentaires pour tous les éléments d’action de votre code converti, choisissez **Tous les messages**.
+ Pour résoudre ce problème, votre base de données Oracle source peut utiliser la `ROWID` pseudocolonne, mais MySQL ne prend pas en charge des fonctionnalités similaires. AWS SCT peut émuler la `ROWID` pseudocolonne dans le code converti. Pour ce faire, choisissez **Generate as identity** pour **Generate row ID ?** .

  Si votre code source Oracle n'utilise pas la `ROWID` pseudocolonne, choisissez **Ne pas générer pour Generate** **row ID ?** Dans ce cas, le code converti fonctionne plus rapidement.
+ Pour travailler avec votre code source Oracle lorsqu'il inclut les `TO_NUMBER` fonctions `TO_CHAR``TO_DATE`, et avec des paramètres que MySQL ne prend pas en charge. Par défaut, AWS SCT émule l'utilisation de ces paramètres dans le code converti.

  Lorsque votre code source Oracle inclut uniquement des paramètres pris en charge par PostgreSQL, vous pouvez utiliser `TO_CHAR` MySQL `TO_DATE` natif et ses fonctions. `TO_NUMBER` Dans ce cas, le code converti fonctionne plus rapidement. Pour inclure uniquement ces paramètres, sélectionnez les valeurs suivantes :
  + **La fonction TO\$1CHAR () n'utilise pas de chaînes de formatage spécifiques à Oracle**
  + **La fonction TO\$1DATE () n'utilise pas de chaînes de formatage spécifiques à Oracle**
  + **La fonction TO\$1NUMBER () n'utilise pas de chaînes de formatage spécifiques à Oracle**
+ Pour déterminer si votre base de données et vos applications s'exécutent dans des fuseaux horaires différents. Par défaut, AWS SCT émule les fuseaux horaires dans le code converti. Toutefois, vous n’avez pas besoin de cette émulation lorsque votre base de données et vos applications utilisent le même fuseau horaire. Dans ce cas, sélectionnez Le **fuseau horaire du côté client correspond au fuseau horaire du serveur**.

## Considérations concernant la migration
<a name="CHAP_Source.Oracle.ToMySQL.MigrationConsiderations"></a>

Lorsque vous convertissez Oracle en RDS for MySQL ou Aurora MySQL, vous pouvez utiliser une `GOTO` instruction et une étiquette pour modifier l'ordre dans lequel les instructions s'exécutent. Toutes les instructions PL/SQL qui suivent une `GOTO` instruction sont ignorées et le traitement se poursuit au niveau de l'étiquette. Vous pouvez utiliser `GOTO` des instructions et des étiquettes n'importe où dans une procédure, un lot ou un bloc d'instructions. Vous pouvez également suivre les instructions GOTO.

MySQL n'utilise pas d'`GOTO`instructions. Lors de la AWS SCT conversion du code contenant une `GOTO` instruction, il convertit l'instruction pour utiliser une `LOOP…END LOOP` instruction `BEGIN…END` or. 

Vous trouverez des exemples de AWS SCT conversion d'`GOTO`instructions dans le tableau suivant.


| Instruction Oracle | Instruction 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>  | 

## Conversion de l'instruction WITH dans Oracle en RDS pour MySQL ou Amazon Aurora MySQL
<a name="CHAP_Source.Oracle.ToMySQL.With"></a>

Vous utilisez la clause WITH (subquery\$1factoring) dans Oracle pour attribuer un nom (query\$1name) à un bloc contenant une sous-requête. Vous pouvez ensuite référencer plusieurs endroits de bloc contenant la sous-requête dans la requête en spécifiant query\$1name. Si un bloc de sous-requête ne contient ni liens ni paramètres (local, procédure, fonction, package), AWS SCT convertit la clause en vue ou en table temporaire. 

L'avantage de convertir la clause en table temporaire est que les références répétées à la sous-requête peuvent être plus efficaces. Cette amélioration de l'efficacité s'explique par le fait que les données sont facilement extraites de la table temporaire au lieu d'être requises par chaque référence. Vous pouvez l'émuler en utilisant des vues supplémentaires ou une table temporaire. Le nom de la vue utilise le format `<procedure_name>$<subselect_alias>`.

Vous trouverez des exemples dans le tableau ci-dessous. 


| Instruction Oracle | Instruction 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>  | 