Convierte MySQL a Oracle
Suelta un volcado de mysqldump, mariadb-dump, mysqlpump, phpMyAdmin o Adminer, en .sql o .sql.gz, y descarga un script de Oracle con las mismas tablas, claves, índices y datos. Cada valor que Oracle no puede guardar tal cual, y cada objeto que no admite, aparece en el informe.
18 filas convertidas, 4 correcciones, ninguna rechazada
Tablas en shop_2024.sqlVolcado de MySQL 8.0.46 · escrito por mysqldump · utf8mb4
customersescrita como CUSTOMERS8 filas2
7 columnas ID NUMBER(10) not null NAME VARCHAR2(100 CHAR) not null EMAIL VARCHAR2(150 CHAR) not null COUNTRY VARCHAR2(2 CHAR) not null IS_ACTIVE NUMBER(1) not null SIGNED_UP DATE CREATED_AT TIMESTAMP(0) WITH TIME ZONE not null ordersescrita como ORDERS10 filas2
9 columnas ID NUMBER(10) not null CUSTOMER_ID NUMBER(10) not null STATUS VARCHAR2(9 CHAR) TOTAL NUMBER(10,2) not null ITEMS NUMBER(5) not null ORDERED_AT TIMESTAMP(0) not null SHIPPED_AT TIMESTAMP(0) NOTE VARCHAR2(255 CHAR) UPDATED_AT TIMESTAMP(0) WITH TIME ZONE not null
-- Written by IntoSQL from a MySQL dump. Load it with: NLS_LANG=.AL32UTF8 sqlplus -S -L <user>/<password>@<database> @<file>
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
SET DEFINE OFF;
SET SQLBLANKLINES ON;
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
CREATE OR REPLACE FUNCTION "INTOSQL_CLOB" (p SYS.ODCIVARCHAR2LIST) RETURN CLOB IS
r CLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(r, TRUE);
FOR i IN 1 .. p.COUNT LOOP
IF p(i) IS NOT NULL THEN
DBMS_LOB.WRITEAPPEND(r, LENGTH2(p(i)), p(i));
END IF;
END LOOP;
RETURN r;
END;
/
CREATE OR REPLACE FUNCTION "INTOSQL_BLOB" (p SYS.ODCIVARCHAR2LIST) RETURN BLOB IS
r BLOB;
piece RAW(2000);
BEGIN
DBMS_LOB.CREATETEMPORARY(r, TRUE);
FOR i IN 1 .. p.COUNT LOOP
piece := HEXTORAW(p(i));
DBMS_LOB.WRITEAPPEND(r, UTL_RAW.LENGTH(piece), piece);
END LOOP;
RETURN r;
END;
/
CREATE TABLE "CUSTOMERS" (
"ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1001),
"NAME" VARCHAR2(100 CHAR) NOT NULL,
"EMAIL" VARCHAR2(150 CHAR) NOT NULL,
"COUNTRY" VARCHAR2(2 CHAR) DEFAULT 'US' NOT NULL,
"IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
"SIGNED_UP" DATE,
"CREATED_AT" TIMESTAMP(0) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
CONSTRAINT "CK_CUSTOMERS_ID" CHECK ("ID" >= 0),
CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1))
);
CREATE TABLE "ORDERS" (
"ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 5001),
"CUSTOMER_ID" NUMBER(10) NOT NULL,
"STATUS" VARCHAR2(9 CHAR) DEFAULT 'pending',
"TOTAL" NUMBER(10,2) NOT NULL,
"ITEMS" NUMBER(5) DEFAULT 1 NOT NULL,
"ORDERED_AT" TIMESTAMP(0) NOT NULL,
"SHIPPED_AT" TIMESTAMP(0),
"NOTE" VARCHAR2(255 CHAR),
"UPDATED_AT" TIMESTAMP(0) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
CONSTRAINT "CK_ORDERS_ID" CHECK ("ID" >= 0),
CONSTRAINT "CK_ORDERS_CUSTOMER_ID" CHECK ("CUSTOMER_ID" >= 0),
CONSTRAINT "CK_ORDERS_STATUS" CHECK ("STATUS" IN ('pending', 'paid', 'shipped', 'cancelled')),
CONSTRAINT "CK_ORDERS_ITEMS" CHECK ("ITEMS" >= 0)
);
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
1,
'Ana Martínez',
'ana@example.com',
'MX',
1,
DATE '2023-01-15',
TIMESTAMP '2023-01-15 10:24:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
2,
'Zoë Müller',
'zoe@example.de',
'DE',
1,
DATE '2023-02-03',
TIMESTAMP '2023-02-03 08:11:42 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
3,
'José Peña',
'jose@example.es',
'ES',
0,
DATE '2023-03-21',
TIMESTAMP '2023-03-21 19:05:17 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
4,
'李雷',
'lilei@example.cn',
'CN',
1,
DATE '2023-05-09',
TIMESTAMP '2023-05-09 02:40:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
5,
'Noah O''Brien',
'noah@example.ie',
'IE',
1,
NULL,
TIMESTAMP '2023-06-30 14:00:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
6,
'Amélie Laurent',
'amelie@example.fr',
'FR',
1,
DATE '2024-01-02',
TIMESTAMP '2024-01-02 09:30:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
7,
'Ravi Patel',
'ravi@example.in',
'IN',
0,
DATE '2024-02-29',
TIMESTAMP '2024-02-29 23:59:59 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
8,
'Sofia Rossi 🌻',
'sofia@example.it',
'IT',
1,
DATE '2024-04-12',
TIMESTAMP '2024-04-12 12:12:12 +00:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
1,
1,
'shipped',
129.90,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL,
TIMESTAMP '2024-03-02 16:30:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
2,
2,
'paid',
54.00,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁',
TIMESTAMP '2024-03-02 11:20:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
3,
1,
'cancelled',
12.50,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind',
TIMESTAMP '2024-03-03 10:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
4,
4,
'shipped',
980.00,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放',
TIMESTAMP '2024-03-07 08:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
5,
5,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door; ring twice',
TIMESTAMP '2024-03-08 17:20:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
6,
6,
'shipped',
310.40,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"',
TIMESTAMP '2024-03-11 09:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
7,
8,
'paid',
76.20,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL,
TIMESTAMP '2024-03-11 18:46:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
8,
2,
NULL,
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Status lost in an old import',
TIMESTAMP '2024-03-12 08:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
9,
3,
'shipped',
64.00,
2,
TIMESTAMP '2024-03-14 15:30:00',
NULL,
'Shipping date never recorded',
TIMESTAMP '2024-03-15 10:00:00 +00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"UPDATED_AT"
) VALUES (
10,
7,
'paid',
1499.00,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf',
TIMESTAMP '2024-03-15 21:05:00 +00:00'
);
COMMIT;
END;
/
-- Keys, indexes, foreign keys, counters and triggers, after the rows.
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "PK_CUSTOMERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "UQ_CUSTOMERS_UQ_EMAIL" UNIQUE ("EMAIL");
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
CREATE INDEX "IX_ORDERS_IDX_CUSTOMER" ON "ORDERS" ("CUSTOMER_ID");
CREATE INDEX "IX_ORDERS_IDX_STATUS_DATE" ON "ORDERS" ("STATUS", "ORDERED_AT");
ALTER TABLE "ORDERS" ADD CONSTRAINT "FK_ORDERS_CUSTOMER" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "FK_ORDERS_CUSTOMER"';
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"FK_ORDERS_CUSTOMER"' || ' has rows without a parent: it stays unvalidated, and new rows are checked.');
END;
/
DECLARE
next_id NUMBER;
BEGIN
SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "CUSTOMERS";
IF next_id < 1001 THEN
next_id := 1001;
END IF;
EXECUTE IMMEDIATE 'ALTER TABLE "CUSTOMERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
COMMENT ON TABLE "CUSTOMERS" IS 'People who bought at least once';
DECLARE
next_id NUMBER;
BEGIN
SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "ORDERS";
IF next_id < 5001 THEN
next_id := 5001;
END IF;
EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
CREATE OR REPLACE TRIGGER "TR_ORDERS_UPDATED_AT" BEFORE UPDATE ON "ORDERS" FOR EACH ROW
BEGIN
IF NOT UPDATING('UPDATED_AT') THEN
:NEW."UPDATED_AT" := SYSTIMESTAMP;
END IF;
END;
/
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;
Correcciones
- "signed_up" de customers ahora admite NULL: algunos de sus valores no se pudieron guardar y quedan en NULL.
- El valor predeterminado de "signed_up" en customers, 0000‑00‑00, no es una fecha que Oracle acepte, así que la columna no tiene valor predeterminado.
- "status" de orders ahora admite NULL: algunos de sus valores no se pudieron guardar y quedan en NULL.
- "updated_at" de orders cambia a la hora actual en cada actualización; en Oracle lo hace un disparador.
Para revisar
- 1 valor en "signed_up" de customers es una fecha cero o imposible, como 0000‑00‑00, que Oracle no puede guardar, así que queda en NULL. Si esas fechas significan algo, reemplázalas en el origen por fechas reales antes del volcado.
- 1 valor en "shipped_at" de orders es una fecha cero o imposible, como 0000‑00‑00 00:00:00, que Oracle no puede guardar, así que queda en NULL. Si esas fechas significan algo, reemplázalas en el origen por fechas reales antes del volcado.
- 1 valor vacío en "status" de orders se volvió NULL; Oracle guarda una cadena vacía como NULL. Donde las consultas comparan esta columna con ', compara con IS NULL.
Tu archivo se convierte en esta computadora y nunca se sube.
Otros ejemplos:
Qué cambia de MySQL a Oracle
Cada fila es una regla que aplica el convertidor, con la línea que escribe en el informe cuando la regla cambia algo en tus datos.
TINYINT(1), BOOL
NUMBER(1) con un CHECK de 0 y 1 cuando cada valor es 0 o 1, si no NUMBER(3)
El BOOL de MySQL es un TINYINT(1) que puede contener cualquier número de -128 a 127. Oracle antes de 23ai no tiene columnas booleanas, así que una columna de 0 y 1 es NUMBER(1) con un CHECK; una que contiene 2 o -1 conserva sus números.
Línea del informe: bool_kept_numeric
UNSIGNED integers
NUMBER con ancho suficiente para el rango, con un CHECK de que no sea negativo
El NUMBER de Oracle admite cualquier entero de los anchos que tiene MySQL; el CHECK deja fuera los valores negativos como hacía MySQL.
ZEROFILL and display widths
se descarta
El relleno con ceros es una forma de mostrar un número, no parte de él. Los números se conservan; dales formato al leerlos si el relleno importa.
Línea del informe: zerofill_dropped
FLOAT(M,D)
BINARY_FLOAT o BINARY_DOUBLE, sin la escala
Los números de punto flotante binarios de Oracle no tienen escala fija. Los valores guardados se copian tal cual.
Línea del informe: float_scale_dropped
DECIMAL(p,s)
NUMBER(p,s) hasta 38 dígitos; VARCHAR2 si son más
El NUMBER de Oracle admite 38 dígitos. Los decimales más anchos se guardan como texto para que cada dígito siga exacto.
Línea del informe: decimal_as_text
BIT(1), BIT(n)
NUMBER(1), NUMBER(19) hasta 63 bits, NUMBER(20) para BIT(64)
Los campos de bits se guardan como el número que forman sus bits.
zero, partial or impossible dates (0000-00-00, 2024-02-30)
NULL
Oracle solo guarda fechas reales del calendario. MySQL conserva fechas cero e imposibles cuando su modo SQL lo permite; se vuelven NULL y el informe las cuenta.
Línea del informe: invalid_date_null
NOT NULL columns with values that become NULL
sin NOT NULL
Una columna cuyos valores tuvieron que volverse NULL, incluidas las cadenas vacías, no puede conservar NOT NULL, o la carga se detendría.
Línea del informe: not_null_relaxed
empty strings and empty binary values
NULL
Oracle guarda una cadena vacía como NULL, así que un valor que era ' se lee como NULL. El informe los cuenta por columna.
Línea del informe: empty_string_null
DEFAULT '0000-00-00'
sin valor predeterminado
Un valor predeterminado que Oracle no puede guardar se deja fuera en lugar de reemplazarse por una fecha inventada.
Línea del informe: zero_date_default
TIME
INTERVAL DAY TO SECOND, que admite duraciones
Oracle no tiene un tipo para la hora del día, y el TIME de MySQL es una duración de -838:59:59 a 838:59:59; un intervalo admite cada valor.
YEAR
NUMBER(4) con un CHECK de su rango
Oracle no tiene un tipo para años; el CHECK conserva los mismos valores que MySQL permite.
CHAR(n), VARCHAR(n)
VARCHAR2(n CHAR), contando caracteres
Las longitudes cuentan caracteres como las de MySQL, y MySQL devuelve los valores CHAR sin espacios finales, como los conserva VARCHAR2.
VARCHAR(n) and TEXT longer than 4000 bytes
CLOB
Un VARCHAR2 admite 4000 bytes por defecto, así que el texto más largo es un CLOB; una columna cuyos valores caben todos conserva VARCHAR2.
Línea del informe: text_as_lob
DATETIME
TIMESTAMP
Un DATETIME es una lectura de reloj sin zona horaria, como TIMESTAMP. DATE se vuelve el DATE de Oracle, que también guarda una hora del día que se queda en medianoche.
TIMESTAMP
TIMESTAMP WITH TIME ZONE en la zona que indica el volcado, UTC si no indica ninguna
Un TIMESTAMP es un instante. Los volcados indican la zona en que lo escribieron (mysqldump escribe UTC); si no la indican, los valores se leen como UTC y el informe lo dice.
Línea del informe: timestamp_zone_assumed
ENUM
VARCHAR2 con un CHECK de sus valores
El texto con un CHECK conserva los mismos valores.
ENUM holding '' (MySQL's error value)
NULL
MySQL guarda una cadena vacía cuando un valor no válido entra en un ENUM en un modo SQL permisivo. Oracle la guarda como NULL, que el CHECK admite, y el informe la cuenta con los demás valores vacíos.
ENUM holding values outside its list
sin CHECK
Los valores que la lista no nombra no cumplirían el CHECK, así que el CHECK no se crea.
Línea del informe: enum_check_skipped
SET
VARCHAR2 tal como lo escribe MySQL ('a,b')
Oracle no tiene un tipo de conjunto; el texto es el que devuelve MySQL.
JSON
CLOB
Las funciones JSON de Oracle leen JSON desde texto en cada versión, y un CLOB guarda valores de cualquier tamaño.
NUL bytes in text
se conserva
VARCHAR2 y CLOB pueden contener un carácter NUL, así que el valor se copia tal cual.
text that isn't valid in its character set
los bytes incorrectos como carácter de reemplazo
El texto tiene que leerse como caracteres para escribirse como VARCHAR2.
Línea del informe: invalid_utf8_replaced
text decoded twice (ñ)
se copia tal cual
El volcado contiene exactamente estos caracteres, así que se copian; el informe los señala.
Línea del informe: mojibake_suspected
AUTO_INCREMENT
GENERATED BY DEFAULT ON NULL AS IDENTITY, reiniciado después de los ids copiados
Los ids copiados se cargan tal cual, y el contador sigue después del más alto o del AUTO_INCREMENT del volcado, el que sea mayor.
MyISAM AUTO_INCREMENT on the second column of a key
un contador para la tabla
MyISAM cuenta por grupo de la primera columna de la clave; Oracle tiene un contador por tabla.
Línea del informe: myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMP
un disparador BEFORE UPDATE
El disparador pone la hora actual en la columna cuando una actualización no la asigna.
Línea del informe: on_update_trigger
generated columns
columnas virtuales
Oracle solo calcula las columnas generadas al leer; las columnas STORED se vuelven virtuales con los mismos valores.
Línea del informe: stored_as_virtual
generated columns with functions Oracle lacks
una columna simple
Una fórmula que no se puede escribir para Oracle deja una columna simple y una línea en el informe.
Línea del informe: generated_not_translated
INVISIBLE columns
columnas INVISIBLE
Oracle oculta las columnas invisibles de SELECT * como hace MySQL.
CHECK constraints
traducido, en línea en CREATE TABLE
Los CHECK en línea se comprueban al cargar cada fila.
CHECK constraints with functions Oracle lacks
no se crea
Un CHECK que no se puede escribir para Oracle se deja fuera y aparece en el informe.
Línea del informe: check_skipped
CHECK ... NOT ENFORCED
no se crea
MySQL conserva estos CHECK sin aplicarlos, así que las filas pueden no cumplirlos.
Línea del informe: check_not_enforced
defaults with functions Oracle lacks
sin valor predeterminado
Un valor predeterminado que no se puede escribir para Oracle se deja fuera y aparece en el informe.
Línea del informe: default_not_translated
keys and indexes on a prefix, c(20)
un índice sobre SUBSTR de la columna
Un índice de función sobre el mismo inicio de la columna mantiene separadas las mismas filas, e indexa columnas CLOB que Oracle no puede indexar completas.
Línea del informe: prefix_unique
FULLTEXT indexes
no se crea
Oracle Text hace la búsqueda de texto completo con su propio tipo de índice y sus propias consultas.
Línea del informe: fulltext_not_created
SPATIAL indexes
no se crea
Las geometrías se guardan como bytes WKB, que un índice espacial no puede leer.
Línea del informe: spatial_index_not_created
functional indexes, and indexes on whole CLOB or BLOB columns
no se crea
Oracle no puede indexar un objeto grande completo, y algunas funciones de MySQL no tienen equivalente en Oracle.
Línea del informe: index_skipped
foreign keys
después de los datos, ENABLE NOVALIDATE, luego validada con una advertencia si hay huérfanas
Los volcados se cargan con FOREIGN_KEY_CHECKS=0 y MyISAM nunca comprueba, así que las filas sin padre son comunes. La clave comprueba las filas nuevas de inmediato y se valida al final; las filas huérfanas la dejan sin validar con una advertencia en lugar de detener la carga.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT
se descarta
Las claves foráneas de Oracle solo actúan al eliminar, con CASCADE o SET NULL.
Línea del informe: foreign_key_action_unsupported
foreign keys to columns without a unique key
no se crea
Oracle necesita una clave primaria o una restricción única en las columnas referenciadas; InnoDB no.
Línea del informe: foreign_key_skipped
table and column names
en mayúsculas cuando son nombres simples, si no tal como están escritos
Oracle guarda en mayúsculas los nombres escritos sin comillas, así que los nombres simples pasan a mayúsculas y las consultas pueden omitir las comillas; los demás nombres conservan sus mayúsculas y minúsculas y necesitan comillas.
Línea del informe: identifier_renamed
names over 128 bytes
acortado
Los nombres de Oracle 12.2 y posteriores admiten 128 bytes.
Línea del informe: name_shortened
GEOMETRY, POINT, POLYGON...
BLOB con WKB
WKB es el formato estándar que lee cualquier biblioteca espacial; SDO_GEOMETRY necesita los metadatos de Oracle Spatial.
Línea del informe: geometry_as_blob
INET4, INET6, UUID (MariaDB)
VARCHAR2(39), VARCHAR2(36)
Oracle no tiene ninguno de los dos tipos; el texto es el que devuelve MariaDB.
BINARY, VARBINARY, BLOB
RAW hasta 2000 bytes, si no BLOB
Los bytes siguen siendo bytes.
PARTITION BY
una sola tabla
Las filas son las mismas; vuelve a particionar la tabla en Oracle si lo necesita.
Línea del informe: partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)
una tabla con las filas actuales
Un volcado solo contiene las filas actuales.
Línea del informe: system_versioning_dropped
MyISAM, MEMORY and other engines
una tabla normal
Oracle tiene un solo motor de tablas.
Línea del informe: engine_dropped
views, triggers, procedures, functions and events
listados en el informe
Su código está escrito en el lenguaje de MySQL, así que se listan para que los vuelvas a crear.
Línea del informe: not_converted_objects
dumps without CREATE TABLE
tipos leídos de los valores
Un volcado hecho con --no-create-info solo tiene filas, así que los tipos salen de los valores.
Línea del informe: no_schema
geometries in a dump without CREATE TABLE
BLOB con WKB
El formato de geometría de MySQL se reconoce por los valores y se guarda como WKB estándar.
Línea del informe: geometry_inferred
_ci collations
comparación exacta
Oracle compara el texto exactamente, salvo que se le indique otra cosa.
Línea del informe: case_insensitive_collation
SET NAMES utf8 from utf8mb4 tables
se convierte, con una advertencia
El mysqldump de MySQL 5.x escribe utf8 de 3 bytes por defecto y reemplaza cada emoji por un signo de interrogación antes de que cualquier convertidor vea el archivo.
Línea del informe: dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8
se lee como Latin-1 (Windows-1252)
El latin1 de MySQL es Windows-1252, la codificación habitual de esos volcados.
Línea del informe: charset_guessed
sjis, cp932, gbk, big5 dumps
se lee como UTF-8, con una advertencia
Estas codificaciones todavía no se decodifican.
Línea del informe: unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows
se evalúan
Algunas herramientas de volcado escriben los valores como estas llamadas; se leen como los valores que producen, con el WKT geográfico convertido para que la longitud vaya primero.
other expressions in rows
NULL
Un convertidor que no ejecuta una base de datos no puede evaluarlas.
Línea del informe: expression_value
DEFAULT in VALUES
el valor predeterminado de la columna
Un valor predeterminado literal se copia en la fila.
Línea del informe: default_keyword_filled
DEFAULT in VALUES without a literal default
NULL
No hay ningún valor que copiar.
Línea del informe: default_keyword_null
REPLACE and INSERT IGNORE
filas simples
Un volcado tiene una fila por clave, así que las filas son las mismas.
Línea del informe: replace_as_insert
types IntoSQL doesn't know
CLOB
El texto admite cualquier valor; cambia el tipo después de cargar.
Línea del informe: unknown_type
values that don't fit their column
NULL
Un volcado dañado o escrito a mano puede contener valores que su columna no admite; se vuelven NULL para que se cargue el resto.
Línea del informe: invalid_value_null
unreadable geometries
NULL
Los bytes que no son una geometría no se pueden guardar como una.
Línea del informe: bad_geometry
dumps of several databases
un esquema, cada tabla con el nombre de su base de datos delante
El script carga en el esquema del usuario que lo ejecuta, así que las tablas de distintas bases de datos llevan delante el nombre de su base de datos.
Línea del informe: databases_merged
CREATE SEQUENCE (MariaDB)
CREATE SEQUENCE, en el valor que había alcanzado
Las secuencias de Oracle funcionan igual.
VECTOR(n) (MariaDB 11.7+)
CLOB con los números de punto flotante como arreglo JSON
Solo Oracle 23ai tiene un tipo vector; un arreglo JSON conserva cada número en todas las versiones.
Línea del informe: type_replaced
| En MySQL | En Oracle | Línea del informe |
|---|---|---|
| TINYINT(1), BOOL | NUMBER(1) con un CHECK de 0 y 1 cuando cada valor es 0 o 1, si no NUMBER(3)El BOOL de MySQL es un TINYINT(1) que puede contener cualquier número de -128 a 127. Oracle antes de 23ai no tiene columnas booleanas, así que una columna de 0 y 1 es NUMBER(1) con un CHECK; una que contiene 2 o -1 conserva sus números. | bool_kept_numeric |
| UNSIGNED integers | NUMBER con ancho suficiente para el rango, con un CHECK de que no sea negativoEl NUMBER de Oracle admite cualquier entero de los anchos que tiene MySQL; el CHECK deja fuera los valores negativos como hacía MySQL. | |
| ZEROFILL and display widths | se descartaEl relleno con ceros es una forma de mostrar un número, no parte de él. Los números se conservan; dales formato al leerlos si el relleno importa. | zerofill_dropped |
| FLOAT(M,D) | BINARY_FLOAT o BINARY_DOUBLE, sin la escalaLos números de punto flotante binarios de Oracle no tienen escala fija. Los valores guardados se copian tal cual. | float_scale_dropped |
| DECIMAL(p,s) | NUMBER(p,s) hasta 38 dígitos; VARCHAR2 si son másEl NUMBER de Oracle admite 38 dígitos. Los decimales más anchos se guardan como texto para que cada dígito siga exacto. | decimal_as_text |
| BIT(1), BIT(n) | NUMBER(1), NUMBER(19) hasta 63 bits, NUMBER(20) para BIT(64)Los campos de bits se guardan como el número que forman sus bits. | |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULLOracle solo guarda fechas reales del calendario. MySQL conserva fechas cero e imposibles cuando su modo SQL lo permite; se vuelven NULL y el informe las cuenta. | invalid_date_null |
| NOT NULL columns with values that become NULL | sin NOT NULLUna columna cuyos valores tuvieron que volverse NULL, incluidas las cadenas vacías, no puede conservar NOT NULL, o la carga se detendría. | not_null_relaxed |
| empty strings and empty binary values | NULLOracle guarda una cadena vacía como NULL, así que un valor que era ' se lee como NULL. El informe los cuenta por columna. | empty_string_null |
| DEFAULT '0000-00-00' | sin valor predeterminadoUn valor predeterminado que Oracle no puede guardar se deja fuera en lugar de reemplazarse por una fecha inventada. | zero_date_default |
| TIME | INTERVAL DAY TO SECOND, que admite duracionesOracle no tiene un tipo para la hora del día, y el TIME de MySQL es una duración de -838:59:59 a 838:59:59; un intervalo admite cada valor. | |
| YEAR | NUMBER(4) con un CHECK de su rangoOracle no tiene un tipo para años; el CHECK conserva los mismos valores que MySQL permite. | |
| CHAR(n), VARCHAR(n) | VARCHAR2(n CHAR), contando caracteresLas longitudes cuentan caracteres como las de MySQL, y MySQL devuelve los valores CHAR sin espacios finales, como los conserva VARCHAR2. | |
| VARCHAR(n) and TEXT longer than 4000 bytes | CLOBUn VARCHAR2 admite 4000 bytes por defecto, así que el texto más largo es un CLOB; una columna cuyos valores caben todos conserva VARCHAR2. | text_as_lob |
| DATETIME | TIMESTAMPUn DATETIME es una lectura de reloj sin zona horaria, como TIMESTAMP. DATE se vuelve el DATE de Oracle, que también guarda una hora del día que se queda en medianoche. | |
| TIMESTAMP | TIMESTAMP WITH TIME ZONE en la zona que indica el volcado, UTC si no indica ningunaUn TIMESTAMP es un instante. Los volcados indican la zona en que lo escribieron (mysqldump escribe UTC); si no la indican, los valores se leen como UTC y el informe lo dice. | timestamp_zone_assumed |
| ENUM | VARCHAR2 con un CHECK de sus valoresEl texto con un CHECK conserva los mismos valores. | |
| ENUM holding '' (MySQL's error value) | NULLMySQL guarda una cadena vacía cuando un valor no válido entra en un ENUM en un modo SQL permisivo. Oracle la guarda como NULL, que el CHECK admite, y el informe la cuenta con los demás valores vacíos. | |
| ENUM holding values outside its list | sin CHECKLos valores que la lista no nombra no cumplirían el CHECK, así que el CHECK no se crea. | enum_check_skipped |
| SET | VARCHAR2 tal como lo escribe MySQL ('a,b')Oracle no tiene un tipo de conjunto; el texto es el que devuelve MySQL. | |
| JSON | CLOBLas funciones JSON de Oracle leen JSON desde texto en cada versión, y un CLOB guarda valores de cualquier tamaño. | |
| NUL bytes in text | se conservaVARCHAR2 y CLOB pueden contener un carácter NUL, así que el valor se copia tal cual. | |
| text that isn't valid in its character set | los bytes incorrectos como carácter de reemplazoEl texto tiene que leerse como caracteres para escribirse como VARCHAR2. | invalid_utf8_replaced |
| text decoded twice (ñ) | se copia tal cualEl volcado contiene exactamente estos caracteres, así que se copian; el informe los señala. | mojibake_suspected |
| AUTO_INCREMENT | GENERATED BY DEFAULT ON NULL AS IDENTITY, reiniciado después de los ids copiadosLos ids copiados se cargan tal cual, y el contador sigue después del más alto o del AUTO_INCREMENT del volcado, el que sea mayor. | |
| MyISAM AUTO_INCREMENT on the second column of a key | un contador para la tablaMyISAM cuenta por grupo de la primera columna de la clave; Oracle tiene un contador por tabla. | myisam_group_autoincrement |
| ON UPDATE CURRENT_TIMESTAMP | un disparador BEFORE UPDATEEl disparador pone la hora actual en la columna cuando una actualización no la asigna. | on_update_trigger |
| generated columns | columnas virtualesOracle solo calcula las columnas generadas al leer; las columnas STORED se vuelven virtuales con los mismos valores. | stored_as_virtual |
| generated columns with functions Oracle lacks | una columna simpleUna fórmula que no se puede escribir para Oracle deja una columna simple y una línea en el informe. | generated_not_translated |
| INVISIBLE columns | columnas INVISIBLEOracle oculta las columnas invisibles de SELECT * como hace MySQL. | |
| CHECK constraints | traducido, en línea en CREATE TABLELos CHECK en línea se comprueban al cargar cada fila. | |
| CHECK constraints with functions Oracle lacks | no se creaUn CHECK que no se puede escribir para Oracle se deja fuera y aparece en el informe. | check_skipped |
| CHECK ... NOT ENFORCED | no se creaMySQL conserva estos CHECK sin aplicarlos, así que las filas pueden no cumplirlos. | check_not_enforced |
| defaults with functions Oracle lacks | sin valor predeterminadoUn valor predeterminado que no se puede escribir para Oracle se deja fuera y aparece en el informe. | default_not_translated |
| keys and indexes on a prefix, c(20) | un índice sobre SUBSTR de la columnaUn índice de función sobre el mismo inicio de la columna mantiene separadas las mismas filas, e indexa columnas CLOB que Oracle no puede indexar completas. | prefix_unique |
| FULLTEXT indexes | no se creaOracle Text hace la búsqueda de texto completo con su propio tipo de índice y sus propias consultas. | fulltext_not_created |
| SPATIAL indexes | no se creaLas geometrías se guardan como bytes WKB, que un índice espacial no puede leer. | spatial_index_not_created |
| functional indexes, and indexes on whole CLOB or BLOB columns | no se creaOracle no puede indexar un objeto grande completo, y algunas funciones de MySQL no tienen equivalente en Oracle. | index_skipped |
| foreign keys | después de los datos, ENABLE NOVALIDATE, luego validada con una advertencia si hay huérfanasLos volcados se cargan con FOREIGN_KEY_CHECKS=0 y MyISAM nunca comprueba, así que las filas sin padre son comunes. La clave comprueba las filas nuevas de inmediato y se valida al final; las filas huérfanas la dejan sin validar con una advertencia en lugar de detener la carga. | |
| ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT | se descartaLas claves foráneas de Oracle solo actúan al eliminar, con CASCADE o SET NULL. | foreign_key_action_unsupported |
| foreign keys to columns without a unique key | no se creaOracle necesita una clave primaria o una restricción única en las columnas referenciadas; InnoDB no. | foreign_key_skipped |
| table and column names | en mayúsculas cuando son nombres simples, si no tal como están escritosOracle guarda en mayúsculas los nombres escritos sin comillas, así que los nombres simples pasan a mayúsculas y las consultas pueden omitir las comillas; los demás nombres conservan sus mayúsculas y minúsculas y necesitan comillas. | identifier_renamed |
| names over 128 bytes | acortadoLos nombres de Oracle 12.2 y posteriores admiten 128 bytes. | name_shortened |
| GEOMETRY, POINT, POLYGON... | BLOB con WKBWKB es el formato estándar que lee cualquier biblioteca espacial; SDO_GEOMETRY necesita los metadatos de Oracle Spatial. | geometry_as_blob |
| INET4, INET6, UUID (MariaDB) | VARCHAR2(39), VARCHAR2(36)Oracle no tiene ninguno de los dos tipos; el texto es el que devuelve MariaDB. | |
| BINARY, VARBINARY, BLOB | RAW hasta 2000 bytes, si no BLOBLos bytes siguen siendo bytes. | |
| PARTITION BY | una sola tablaLas filas son las mismas; vuelve a particionar la tabla en Oracle si lo necesita. | partitions_dropped |
| WITH SYSTEM VERSIONING (MariaDB) | una tabla con las filas actualesUn volcado solo contiene las filas actuales. | system_versioning_dropped |
| MyISAM, MEMORY and other engines | una tabla normalOracle tiene un solo motor de tablas. | engine_dropped |
| views, triggers, procedures, functions and events | listados en el informeSu código está escrito en el lenguaje de MySQL, así que se listan para que los vuelvas a crear. | not_converted_objects |
| dumps without CREATE TABLE | tipos leídos de los valoresUn volcado hecho con --no-create-info solo tiene filas, así que los tipos salen de los valores. | no_schema |
| geometries in a dump without CREATE TABLE | BLOB con WKBEl formato de geometría de MySQL se reconoce por los valores y se guarda como WKB estándar. | geometry_inferred |
| _ci collations | comparación exactaOracle compara el texto exactamente, salvo que se le indique otra cosa. | case_insensitive_collation |
| SET NAMES utf8 from utf8mb4 tables | se convierte, con una advertenciaEl mysqldump de MySQL 5.x escribe utf8 de 3 bytes por defecto y reemplaza cada emoji por un signo de interrogación antes de que cualquier convertidor vea el archivo. | dump_lost_four_byte_chars |
| dumps without SET NAMES whose text isn't UTF-8 | se lee como Latin-1 (Windows-1252)El latin1 de MySQL es Windows-1252, la codificación habitual de esos volcados. | charset_guessed |
| sjis, cp932, gbk, big5 dumps | se lee como UTF-8, con una advertenciaEstas codificaciones todavía no se decodifican. | unsupported_charset |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | se evalúanAlgunas herramientas de volcado escriben los valores como estas llamadas; se leen como los valores que producen, con el WKT geográfico convertido para que la longitud vaya primero. | |
| other expressions in rows | NULLUn convertidor que no ejecuta una base de datos no puede evaluarlas. | expression_value |
| DEFAULT in VALUES | el valor predeterminado de la columnaUn valor predeterminado literal se copia en la fila. | default_keyword_filled |
| DEFAULT in VALUES without a literal default | NULLNo hay ningún valor que copiar. | default_keyword_null |
| REPLACE and INSERT IGNORE | filas simplesUn volcado tiene una fila por clave, así que las filas son las mismas. | replace_as_insert |
| types IntoSQL doesn't know | CLOBEl texto admite cualquier valor; cambia el tipo después de cargar. | unknown_type |
| values that don't fit their column | NULLUn volcado dañado o escrito a mano puede contener valores que su columna no admite; se vuelven NULL para que se cargue el resto. | invalid_value_null |
| unreadable geometries | NULLLos bytes que no son una geometría no se pueden guardar como una. | bad_geometry |
| dumps of several databases | un esquema, cada tabla con el nombre de su base de datos delanteEl script carga en el esquema del usuario que lo ejecuta, así que las tablas de distintas bases de datos llevan delante el nombre de su base de datos. | databases_merged |
| CREATE SEQUENCE (MariaDB) | CREATE SEQUENCE, en el valor que había alcanzadoLas secuencias de Oracle funcionan igual. | |
| VECTOR(n) (MariaDB 11.7+) | CLOB con los números de punto flotante como arreglo JSONSolo Oracle 23ai tiene un tipo vector; un arreglo JSON conserva cada número en todas las versiones. | type_replaced |
Carga el script en Oracle
El script crea las tablas, copia las filas y luego agrega claves, índices y claves foráneas, así que carga rápido y se detiene en el primer error.
NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @mysql.oracle.sqlLas claves foráneas se agregan ENABLE NOVALIDATE, así que las filas nuevas se comprueban de inmediato, y luego se validan. Si una fila antigua apunta a una fila que no existe, el script dice qué restricción es y la deja sin validar, en lugar de fallar a medias.
Para un volcado grande, ejecuta SQL*Plus en la misma máquina que la base de datos. El script confirma cada 100 filas. El usuario que lo ejecuta necesita CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER y CREATE PROCEDURE, y cuota en su tablespace.
Haz el volcado de MySQL para el mejor resultado
El convertidor lee lo que contiene el volcado. Estas opciones conservan más de tus datos en él:
- --default-character-set=utf8mb4 conserva los emoji y otros caracteres de 4 bytes, que un volcado utf8 pierde antes de que el convertidor lo vea.
- --hex-blob escribe las columnas binarias en hexadecimal, que sobrevive a la copia entre sistemas.
- --routines --triggers --events agregan esos objetos al volcado, para que el informe pueda listarlos.
Qué no se convierte
Las vistas, los disparadores, los procedimientos almacenados, las funciones y los eventos se escriben en el lenguaje propio de cada base de datos. Aparecen en el informe por nombre, nunca se descartan en silencio, para que puedas reescribirlos para Oracle.
Preguntas sobre MySQL a Oracle
¿No encuentras la respuesta? Escríbenos desde la página de contacto y te responde una persona. Página de contacto
¿Se sube mi volcado?
No. El convertidor se ejecuta en tu navegador y lee el volcado de tu disco por partes, así que nunca sale de tu computadora. La app de escritorio y la línea de comandos también convierten en tu computadora.
¿Qué tan grande puede ser el volcado?
El convertidor nunca tiene todo el volcado en memoria: lee el archivo dos veces, por rangos, y escribe el script sobre la marcha. Los volcados de varios gigabytes se convierten en el navegador, en la app de escritorio y con la línea de comandos.
¿Lee volcados de MariaDB?
Sí. Los volcados de mariadb-dump y de MariaDB 10.3 a 12 se convierten de la misma forma, incluidas las columnas INET6, INET4 y UUID de MariaDB.
¿Qué pasa con las fechas 0000-00-00?
Oracle no tiene fecha cero, así que se vuelven NULL y la columna acepta NULL. El informe dice cuántas había en cada columna. Las cadenas vacías también se vuelven NULL, como las guarda Oracle.
¿Se conservan los valores AUTO_INCREMENT?
Sí. Cada columna AUTO_INCREMENT se vuelve una columna de identidad, cada fila conserva su id, y el siguiente id sigue después del más alto, o después del AUTO_INCREMENT de la tabla si es mayor.
¿TINYINT(1) se vuelve boolean?
Oracle antes de 23ai no tiene columnas booleanas. Una columna cuyos valores son todos 0 o 1 se vuelve NUMBER(1) con un CHECK que la mantiene así; una que contiene otros números los conserva, y el informe dice por qué.
¿Qué pasa con los procedimientos almacenados y los disparadores?
Aparecen en el informe por nombre y no se convierten, porque cada base de datos los escribe en su propio lenguaje. ON UPDATE CURRENT_TIMESTAMP es la excepción: se vuelve un disparador de Oracle.
¿En qué versiones de Oracle carga el script?
Oracle 19c y posteriores. Cada volcado de prueba carga en 21c y 23ai, y se detiene en el primer error si algo sale mal.