

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Migración de Oracle a Amazon RDS para MySQL o Amazon Aurora MySQL con AWS Schema Conversion Tool
<a name="CHAP_Source.Oracle.ToMySQL"></a>

Para simular las funciones de la base de datos de Oracle en código MySQL convertido, utilice el paquete de extensión de Oracle a MySQL en AWS SCT. Para obtener más información acerca de los paquetes de extensión , consulte [Uso de paquetes de extensión con AWS Schema Conversion Tool](CHAP_ExtensionPack.md). 

**Topics**
+ [Privilegios para MySQL como base de datos de destino](#CHAP_Source.Oracle.ToMySQL.ConfigureTarget)
+ [Configuración de conversión de Oracle a MySQL](#CHAP_Source.Oracle.ToMySQL.ConversionSettings)
+ [Consideraciones sobre la migración](#CHAP_Source.Oracle.ToMySQL.MigrationConsiderations)
+ [Convertir la instrucción WITH en Oracle a Amazon RDS para MySQL o Amazon Aurora MySQL](#CHAP_Source.Oracle.ToMySQL.With)

## Privilegios para MySQL como base de datos de destino
<a name="CHAP_Source.Oracle.ToMySQL.ConfigureTarget"></a>

Los privilegios necesarios para MySQL como destino se enumeran a continuación:
+ 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
+ INSERTAR, ACTUALIZAR EN AWS\$1ORACLE \$1EXT. \$1
+ INSERTAR, ACTUALIZAR Y ELIMINAR EN AWS\$1ORACLE \$1EXT\$1DATA. \$1

Si utiliza como destino una base de datos MySQL 5.7 o inferior, conceda el permiso INVOKE LAMBDA \$1.\$1 en lugar de \$1ACCESS. AWS\$1LAMBDA Para las bases de datos MySQL versión 8.0 y superiores, conceda el AWS\$1LAMBDA\$1ACCESS permiso.

Puede usar el siguiente ejemplo de código para crear un usuario de base de datos y conceder los privilegios.

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

En el ejemplo anterior, *user\$1name* sustitúyalo por el nombre de tu usuario. A continuación, *your\$1password* sustitúyala por una contraseña segura.

Si utiliza como destino una base de datos MySQL 5.7 o anterior, utilice `GRANT INVOKE LAMBDA ON *.* TO 'user_name'` en lugar de `GRANT AWS_LAMBDA_ACCESS TO 'user_name'`.

Para usar Amazon RDS para MySQL o Aurora MySQL como destino, establezca el parámetro `lower_case_table_names` en `1`. Este valor significa que el servidor MySQL gestiona los identificadores de nombres de objetos como tablas, índices, disparadores y bases de datos sin distinguir entre mayúsculas y minúsculas. Si ha activado el registro binario en la instancia de destino, establezca el parámetro `log_bin_trust_function_creators` en `1`. En este caso, no es necesario utilizar las características `DETERMINISTIC`, `READS SQL DATA` o `NO SQL` para crear funciones almacenadas. Para configurar estos parámetros, cree un grupo de parámetros de base de datos nuevo o modifique uno existente.

## Configuración de conversión de Oracle a MySQL
<a name="CHAP_Source.Oracle.ToMySQL.ConversionSettings"></a>

Para editar la configuración de conversión de Oracle a MySQL, seleccione **Configuración** en y AWS SCT, a continuación, elija **Configuración de conversión**. En la lista superior, elija **Oracle** y, a continuación, **Oracle — MySQL**. AWS SCT muestra todos los ajustes disponibles para la conversión de Oracle a MySQL.

La configuración de conversión de Oracle a MySQL AWS SCT incluye opciones para lo siguiente:
+ Limitar el número de comentarios con elementos de acción en el código convertido.

  En **Añadir comentarios en el código convertido para los elementos de acción de la gravedad seleccionada o superior**, selecciona la gravedad de los elementos de acción. AWS SCT añade comentarios en el código convertido para los elementos de acción de la gravedad seleccionada o superior.

  Por ejemplo, para minimizar el número de comentarios en el código convertido, seleccione **Solo errores**. Para incluir comentarios para todos los elementos de acción del código convertido, seleccione **Todos los mensajes**.
+ Para solucionarlo, su base de datos Oracle de origen puede utilizar la `ROWID` pseudocolumna, pero MySQL no admite una funcionalidad similar. AWS SCT puede emular la `ROWID` pseudocolumna en el código convertido. Para ello, elija **Generar como identidad** en **¿Generar ID de fila?**.

  Si el código fuente de Oracle no utiliza la pseudocolumna `ROWID`, seleccione **No generar para generar** en **¿Generar ID de fila?** En este caso, el código convertido funciona más rápido.
+ Trabajar con el código fuente de Oracle cuando incluye las funciones `TO_CHAR`, `TO_DATE` y `TO_NUMBER` con parámetros que MySQL no admite. De forma predeterminada, AWS SCT simula el uso de estos parámetros en el código convertido.

  Si el código fuente de Oracle incluye solo los parámetros compatibles con PostgreSQL, puede utilizar funciones `TO_CHAR`, `TO_DATE` y `TO_NUMBER` de MySQL nativas. En este caso, el código convertido funciona más rápido. Para incluir solo estos parámetros, seleccione los siguientes valores:
  + **La función TO\$1CHAR() no utiliza cadenas de formato específicas de Oracle**
  + **La función TO\$1DATE() no utiliza cadenas de formato específicas de Oracle**
  + **La función TO\$1NUMBER() no utiliza cadenas de formato específicas de Oracle**
+ Determinar si la base de datos y las aplicaciones se ejecutan en zonas horarias diferentes. De forma predeterminada, AWS SCT simula las zonas horarias del código convertido. Sin embargo, no necesita esta simulación cuando la base de datos y las aplicaciones utilizan la misma zona horaria. En este caso, seleccione **La zona horaria del cliente coincide con la zona horaria del servidor**.

## Consideraciones sobre la migración
<a name="CHAP_Source.Oracle.ToMySQL.MigrationConsiderations"></a>

Al convertir Oracle a RDS para MySQL o Aurora MySQL, para cambiar el orden en que se ejecutan las sentencias, puede utilizar una instrucción `GOTO` y una etiqueta. Todas las instrucciones PL/SQL que van detrás de una instrucción `GOTO` se omiten y el procesamiento continúa en la etiqueta. Puede usar las instrucciones `GOTO` y las etiquetas se pueden utilizar en cualquier lugar de un procedimiento, lote o bloque de instrucciones. También puede anidar las instrucciones GOTO.

MySQL no utiliza instrucciones `GOTO`. Cuando AWS SCT convierte el código que contiene una `GOTO` sentencia, convierte la sentencia para usar una sentencia `BEGIN…END` or`LOOP…END LOOP`. 

Puede encontrar ejemplos de cómo se AWS SCT convierten `GOTO` las sentencias en la siguiente tabla.


| Instrucción de Oracle | Instrucción de 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>  | 

## Convertir la instrucción WITH en Oracle a Amazon RDS para MySQL o Amazon Aurora MySQL
<a name="CHAP_Source.Oracle.ToMySQL.With"></a>

Puede utilizar la cláusula WITH (subquery\$1factoring) en Oracle para asignar un nombre (query\$1name) a un bloque subquery. A continuación, puede hacer referencia al bloque subquery en varios lugares de la consulta especificando el valor de query\$1name. Si un bloque de subconsultas no contiene enlaces ni parámetros (local, procedimiento, función, paquete), AWS SCT convierte la cláusula en una vista o una tabla temporal. 

El beneficio de convertir la cláusula en una tabla temporal es que las referencias repetidas a la subconsulta podrían ser más eficientes. La mayor eficiencia se debe a que los datos se recuperan fácilmente de la tabla temporal en lugar de que cada referencia tenga que solicitarlos. Puede emular esto mediante vistas adicionales o una tabla temporal. El nombre de la consulta utiliza el formato `<procedure_name>$<subselect_alias>`.

Puede encontrar ejemplos en la siguiente tabla. 


| Instrucción de Oracle | Instrucción de 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>  | 