Saltar al contenido
Inicio de IntoSQL

Convierte SQLite a Oracle

Suelta un archivo de base de datos SQLite (.db, .sqlite, .sqlite3) o el SQL que escribe .dump de sqlite3, y descarga un script de Oracle con las mismas tablas, claves, índices y datos. Cada columna recibe el tipo en el que caben sus valores, y cada valor que Oracle no puede guardar tal cual aparece en el informe.

Tu archivo
sqlshop_2024_sqlite.sqlArchivo de ejemplo, 3,4 kB
Tu base de datos

18 filas convertidas, sin correcciones, ninguna rechazada

Mostrar

Tablas en shop_2024_sqlite.sqlVolcado de SQLite · escrito por sqlite3 · utf-8

  • customersescrita como CUSTOMERS8 filas
    7 columnas
    IDNUMBER(19) not null
    NAMEVARCHAR2(4000 CHAR) not null
    EMAILVARCHAR2(750 CHAR) not null
    COUNTRYVARCHAR2(4000 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) not null
  • ordersescrita como ORDERS10 filas
    9 columnas
    IDNUMBER(19) not null
    CUSTOMER_IDNUMBER(19) not null
    STATUSVARCHAR2(750 CHAR) not null
    TOTALNUMBER(10,2) not null
    ITEMSNUMBER(10) not null
    ORDERED_ATTIMESTAMP(0) not null
    SHIPPED_ATTIMESTAMP(0)
    NOTEVARCHAR2(4000 CHAR)
    RECEIPTBLOB

Sin convertir

  • Vista order_totals
  • Disparador orders_shipped

Cada base de datos los escribe en su propio lenguaje. Reescríbelos para Oracle.

-- Written by IntoSQL from a SQLite 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(19) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 9),
    "NAME" VARCHAR2(4000 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(750 CHAR) NOT NULL,
    "COUNTRY" VARCHAR2(4000 CHAR) DEFAULT 'US' NOT NULL,
    "IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
    "SIGNED_UP" DATE,
    "CREATED_AT" TIMESTAMP(0) DEFAULT LOCALTIMESTAMP NOT NULL,
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1)),
    CONSTRAINT "CHECK1" CHECK (LENGTH("COUNTRY") = 2)
);

CREATE TABLE "ORDERS" (
    "ID" NUMBER(19) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 11),
    "CUSTOMER_ID" NUMBER(19) NOT NULL,
    "STATUS" VARCHAR2(750 CHAR) DEFAULT 'pending' NOT NULL,
    "TOTAL" NUMBER(10,2) NOT NULL,
    "ITEMS" NUMBER(10) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(0) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(0),
    "NOTE" VARCHAR2(4000 CHAR),
    "RECEIPT" BLOB,
    CONSTRAINT "CHECK1_2" CHECK ("STATUS" IN ('pending', 'paid', 'shipped', 'cancelled'))
);

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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
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'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
1,
1,
'shipped',
129.9,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL,
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
2,
2,
'paid',
54,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
3,
1,
'cancelled',
12.5,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
4,
4,
'shipped',
980,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放',
HEXTORAW('25504446')
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
5,
5,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door;'
|| CHR(10)
|| 'ring twice',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
6,
6,
'shipped',
310.4,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
7,
8,
'paid',
76.2,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL,
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
8,
2,
'paid',
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Paid at the counter',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
9,
3,
'shipped',
64,
2,
TIMESTAMP '2024-03-14 15:30:00',
NULL,
'Shipping date never recorded',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"RECEIPT"
) VALUES (
10,
7,
'paid',
1499,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf',
NULL
);
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_EMAIL" UNIQUE ("EMAIL");
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
CREATE INDEX "IX_ORDERS_IDX_ORDERS_CUSTOMER" ON "ORDERS" ("CUSTOMER_ID");
CREATE INDEX "IX_ORDERS_IDX_ORDERS_STATUS_DATE" ON "ORDERS" ("STATUS", "ORDERED_AT");
ALTER TABLE "ORDERS" ADD CONSTRAINT "FK_ORDERS" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ON DELETE CASCADE ENABLE NOVALIDATE;
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "FK_ORDERS"';
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"FK_ORDERS"' || ' 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 < 9 THEN
        next_id := 9;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "CUSTOMERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "ORDERS";
    IF next_id < 11 THEN
        next_id := 11;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

Correcciones

No hubo nada que corregir.

Para revisar

  • 1 columna de texto compara sin distinguir mayúsculas en el origen; Oracle compara exactamente, así que las claves únicas y las búsquedas pueden comportarse distinto. Usa una intercalación o un tipo de columna que no distinga mayúsculas en las columnas que lo necesiten.
  • 2 vistas, disparadores, rutinas o eventos no se convierten; el informe lista cada uno. Vuelve a crearlos a mano en Oracle.

Tu archivo se convierte en esta computadora y nunca se sube.

Otros ejemplos:

Qué cambia de SQLite 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.

  • declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)

    el tipo en el que caben todos los valores de la columna

    SQLite guarda cualquier valor en cualquier columna, así que el tipo declarado es una pista: cada columna recibe el tipo en el que caben todos sus valores, y una columna con valores mezclados conserva su texto.

  • BOOLEAN, BOOL

    NUMBER(1) con un CHECK de 0 y 1

    Cuando cada valor es 0 o 1; una columna que también tiene otros valores los conserva como números o texto.

  • TEXT, VARCHAR(n), CHAR(n), CLOB

    VARCHAR2(n CHAR) cuando cada valor cabe, si no CLOB

    SQLite nunca aplica una longitud; una longitud declarada se mantiene solo cuando cada valor cabe en ella.

  • TEXT and VARCHAR(n) longer than 4000 bytes

    VARCHAR2(4000 CHAR) cuando cada valor cabe en 4000 bytes (750 caracteres en una clave), si no CLOB

    Un VARCHAR2 admite 4000 bytes por defecto y Oracle no puede indexar un CLOB, así que el texto se queda en VARCHAR2 cuando sus valores caben y es un CLOB cuando no.

    Línea del informe: text_as_lob

  • DECIMAL(p,s), NUMERIC

    el tipo exacto cuando cada valor cabe en él, si no un double

    SQLite los guarda como enteros o doubles; una precisión declarada se mantiene solo cuando los valores caben en ella.

  • BLOB, and columns holding bytes

    BLOB

    Los bytes siguen siendo bytes; el texto y los números de la misma columna se conservan como sus bytes.

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    DATE o TIMESTAMP(p), según lo que contengan los valores

    Cuando cada valor es una fecha o una fecha con hora; los números epoch y el resto del texto conservan sus valores tal cual.

  • JSON holding JSON text

    CLOB

    Cuando cada valor es un objeto o un arreglo JSON.

  • Infinity in REAL columns

    se conserva como BINARY_DOUBLE_INFINITY

    Los doubles de Oracle admiten el infinito.

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    GENERATED BY DEFAULT ON NULL AS IDENTITY, siguiendo después del id más alto o del valor de sqlite_sequence

    Solo una columna declarada exactamente INTEGER PRIMARY KEY es el rowid; cada fila conserva su id, y el contador empieza después del id más alto que se haya asignado.

  • COLLATE NOCASE

    comparación exacta

    Oracle compara el texto exactamente salvo que se indique otra cosa; las columnas NOCASE dejan de ignorar las mayúsculas.

    Línea del informe: case_insensitive_collation

  • 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 IntoSQL doesn't write, and the || operator

    una columna simple

    Una fórmula que no se puede escribir deja una columna simple y una línea en el informe; el volcado no tiene valores para las columnas generadas.

    Línea del informe: generated_not_translated

  • defaults with functions IntoSQL doesn't write (strftime, randomblob)

    sin valor predeterminado

    Un valor predeterminado que no se puede escribir se deja fuera y aparece en el informe; CURRENT_TIMESTAMP y datetime('now') sí se escriben.

    Línea del informe: default_not_translated

  • CHECK constraints

    traducidos

    Los mismos CHECK, comprobados al cargar cada fila.

  • CHECK constraints with functions IntoSQL doesn't write

    no se crea

    Un CHECK que no se puede escribir se deja fuera y aparece en el informe.

    Línea del informe: check_skipped

  • partial and expression indexes

    no se crea

    IntoSQL escribe índices sobre columnas completas; vuelve a crear los demás después de cargar.

    Línea del informe: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    después de los datos, ENABLE NOVALIDATE, luego validada

    SQLite solo comprueba las claves foráneas cuando se le indica, así que las filas sin padre son comunes: se cargan, y la clave queda sin comprobar 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

  • empty strings and empty blobs

    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

  • foreign keys to tables the dump doesn't create

    no se crea

    Una clave no puede nombrar una tabla que no existe.

    Línea del informe: foreign_key_skipped

  • primary keys holding NULL, and NOT NULL columns with values that become NULL

    sin NOT NULL

    SQLite deja que una clave primaria distinta del rowid tenga NULL; la columna no puede ser NOT NULL en el destino, o la carga se detendría.

    Línea del informe: not_null_relaxed

  • views, triggers and virtual tables (FTS, R*Tree)

    listados en el informe

    Su código está escrito en el lenguaje propio de SQLite, y las tablas virtuales necesitan los módulos de SQLite; se listan para que los vuelvas a crear. Sus tablas internas no se copian.

    Línea del informe: not_converted_objects

  • dumps without CREATE TABLE (--data-only)

    tipos leídos de los valores

    Un volcado solo de datos solo tiene filas, así que los tipos salen de los valores y las columnas se numeran.

    Línea del informe: no_schema

  • expressions in INSERT values other than the text functions dumps write

    NULL

    unistr(), replace(), char() y || se evalúan tal como los escribe el shell; las demás expresiones no se pueden evaluar sin una base de datos.

    Línea del informe: expression_value

  • NUL characters in text

    se conserva

    El shell sqlite3 y Python cortan el texto en un carácter NUL al volcarlo, así que en el volcado solo está lo que lo precede.

  • text that isn't valid UTF-8

    los bytes incorrectos como carácter de reemplazo

    Los volcados escriben ese texto como bytes sin procesar; el script es UTF-8.

    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

En SQLiteEn OracleLínea del informe
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)el tipo en el que caben todos los valores de la columnaSQLite guarda cualquier valor en cualquier columna, así que el tipo declarado es una pista: cada columna recibe el tipo en el que caben todos sus valores, y una columna con valores mezclados conserva su texto.
BOOLEAN, BOOLNUMBER(1) con un CHECK de 0 y 1Cuando cada valor es 0 o 1; una columna que también tiene otros valores los conserva como números o texto.
TEXT, VARCHAR(n), CHAR(n), CLOBVARCHAR2(n CHAR) cuando cada valor cabe, si no CLOBSQLite nunca aplica una longitud; una longitud declarada se mantiene solo cuando cada valor cabe en ella.
TEXT and VARCHAR(n) longer than 4000 bytesVARCHAR2(4000 CHAR) cuando cada valor cabe en 4000 bytes (750 caracteres en una clave), si no CLOBUn VARCHAR2 admite 4000 bytes por defecto y Oracle no puede indexar un CLOB, así que el texto se queda en VARCHAR2 cuando sus valores caben y es un CLOB cuando no.text_as_lob
DECIMAL(p,s), NUMERICel tipo exacto cuando cada valor cabe en él, si no un doubleSQLite los guarda como enteros o doubles; una precisión declarada se mantiene solo cuando los valores caben en ella.
BLOB, and columns holding bytesBLOBLos bytes siguen siendo bytes; el texto y los números de la misma columna se conservan como sus bytes.
DATE, DATETIME, TIMESTAMP holding ISO 8601 textDATE o TIMESTAMP(p), según lo que contengan los valoresCuando cada valor es una fecha o una fecha con hora; los números epoch y el resto del texto conservan sus valores tal cual.
JSON holding JSON textCLOBCuando cada valor es un objeto o un arreglo JSON.
Infinity in REAL columnsse conserva como BINARY_DOUBLE_INFINITYLos doubles de Oracle admiten el infinito.
INTEGER PRIMARY KEY, AUTOINCREMENTGENERATED BY DEFAULT ON NULL AS IDENTITY, siguiendo después del id más alto o del valor de sqlite_sequenceSolo una columna declarada exactamente INTEGER PRIMARY KEY es el rowid; cada fila conserva su id, y el contador empieza después del id más alto que se haya asignado.
COLLATE NOCASEcomparación exactaOracle compara el texto exactamente salvo que se indique otra cosa; las columnas NOCASE dejan de ignorar las mayúsculas.case_insensitive_collation
generated columnscolumnas 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 IntoSQL doesn't write, and the || operatoruna columna simpleUna fórmula que no se puede escribir deja una columna simple y una línea en el informe; el volcado no tiene valores para las columnas generadas.generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)sin valor predeterminadoUn valor predeterminado que no se puede escribir se deja fuera y aparece en el informe; CURRENT_TIMESTAMP y datetime('now') sí se escriben.default_not_translated
CHECK constraintstraducidosLos mismos CHECK, comprobados al cargar cada fila.
CHECK constraints with functions IntoSQL doesn't writeno se creaUn CHECK que no se puede escribir se deja fuera y aparece en el informe.check_skipped
partial and expression indexesno se creaIntoSQL escribe índices sobre columnas completas; vuelve a crear los demás después de cargar.index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)después de los datos, ENABLE NOVALIDATE, luego validadaSQLite solo comprueba las claves foráneas cuando se le indica, así que las filas sin padre son comunes: se cargan, y la clave queda sin comprobar con una advertencia en lugar de detener la carga.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTse descartaLas claves foráneas de Oracle solo actúan al eliminar, con CASCADE o SET NULL.foreign_key_action_unsupported
empty strings and empty blobsNULLOracle 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
foreign keys to tables the dump doesn't createno se creaUna clave no puede nombrar una tabla que no existe.foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLsin NOT NULLSQLite deja que una clave primaria distinta del rowid tenga NULL; la columna no puede ser NOT NULL en el destino, o la carga se detendría.not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)listados en el informeSu código está escrito en el lenguaje propio de SQLite, y las tablas virtuales necesitan los módulos de SQLite; se listan para que los vuelvas a crear. Sus tablas internas no se copian.not_converted_objects
dumps without CREATE TABLE (--data-only)tipos leídos de los valoresUn volcado solo de datos solo tiene filas, así que los tipos salen de los valores y las columnas se numeran.no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr(), replace(), char() y || se evalúan tal como los escribe el shell; las demás expresiones no se pueden evaluar sin una base de datos.expression_value
NUL characters in textse conservaEl shell sqlite3 y Python cortan el texto en un carácter NUL al volcarlo, así que en el volcado solo está lo que lo precede.
text that isn't valid UTF-8los bytes incorrectos como carácter de reemplazoLos volcados escriben ese texto como bytes sin procesar; el script es UTF-8.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

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 @sqlite.oracle.sql

Las 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 SQLite para el mejor resultado

El convertidor lee lo que contiene el volcado. Estas opciones conservan más de tus datos en él:

  • El archivo de la base de datos se convierte tal cual, leído página por página en tu navegador. Cierra primero la app que escribe en él, para que ningún cambio se quede en su archivo -wal.
  • sqlite3 app.db .dump > app.sql escribe la misma base de datos como SQL, que también se convierte, en .sql o .sql.gz.
  • DB Browser for SQLite escribe ese SQL con File, Export, Database to SQL file, y también lo hace iterdump() de Python.

Qué no se convierte

Las vistas y los disparadores se escriben en el lenguaje propio de SQLite. Aparecen en el informe por nombre, nunca se descartan en silencio, para que puedas reescribirlos para Oracle. Las tablas virtuales, como FTS5 y R*Tree, también aparecen, y sus tablas internas se dejan fuera.

Preguntas sobre SQLite 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.

¿Puedo convertir directamente el archivo .db?

Sí. Suelta el archivo .db, .sqlite o .sqlite3: se lee en tu navegador y nunca se sube. El texto con caracteres NUL y cada dígito de un double llegan tal como están guardados, algo que un .dump puede recortar.

¿De qué versiones de SQLite puede venir el volcado?

Archivos de base de datos de SQLite 3.0 en adelante, en UTF-8 o UTF-16, y volcados del .dump del shell sqlite3 o de iterdump() de Python. Cada archivo y volcado de prueba viene de sqlite3 3.31 a 3.54, con tablas STRICT y WITHOUT ROWID incluidas, y se compara con su origen celda por celda.

¿Cómo se deciden los tipos de columna si SQLite no los aplica?

El tipo declarado es una pista y los valores deciden: una columna se vuelve NUMBER, BINARY_DOUBLE, DATE, TIMESTAMP, BLOB, VARCHAR2 o CLOB cuando cada valor cabe en ese tipo. Las cadenas vacías se vuelven NULL, como las guarda Oracle, y el informe las cuenta.

¿Se conservan INTEGER PRIMARY KEY y AUTOINCREMENT?

Sí. Una INTEGER PRIMARY KEY 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 valor de sqlite_sequence con AUTOINCREMENT.

¿Qué pasa con las vistas y los disparadores?

Aparecen en el informe por nombre y no se convierten, porque cada base de datos los escribe en su propio lenguaje.

¿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.