Zum Inhalt springen
IntoSQL-Startseite

SQLite in Oracle umwandeln

Leg eine SQLite-Datenbankdatei (.db, .sqlite, .sqlite3) oder das SQL ab, das .dump von sqlite3 schreibt, und lade ein Oracle-Skript mit denselben Tabellen, Schlüsseln, Indizes und Daten herunter. Jede Spalte bekommt den Typ, in den ihre Werte passen, und jeder Wert, den Oracle nicht unverändert aufnehmen kann, steht im Bericht.

Deine Datei
sqlshop_2024_sqlite.sqlBeispieldatei, 3,4 kB
Deine Datenbank

18 Zeilen konvertiert, keine Korrekturen, keine abgelehnt

Anzeigen

Tabellen in shop_2024_sqlite.sqlSQLite-Dump · erstellt mit sqlite3 · utf-8

  • customersgeschrieben als CUSTOMERS8 Zeilen
    7 Spalten
    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
  • ordersgeschrieben als ORDERS10 Zeilen
    9 Spalten
    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

Nicht konvertiert

  • Sicht order_totals
  • Trigger orders_shipped

Jede Datenbank schreibt diese in ihrer eigenen Sprache. Schreib sie für Oracle neu.

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

Korrekturen

Nichts musste korrigiert werden.

Zu prüfen

  • 1 Textspalte vergleicht in der Quelle ohne Rücksicht auf Groß- und Kleinschreibung; Oracle vergleicht exakt, daher können sich eindeutige Schlüssel und Suchen anders verhalten. Nutze eine Collation oder einen Spaltentyp ohne Unterscheidung der Groß- und Kleinschreibung für die Spalten, die das brauchen.
  • 2 Sichten, Trigger, Routinen oder Ereignisse werden nicht konvertiert; der Bericht listet sie einzeln auf. Lege sie in Oracle von Hand neu an.

Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.

Weitere Beispiele:

Was sich von SQLite zu Oracle ändert

Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.

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

    der Typ, in den jeder Wert der Spalte passt

    SQLite speichert jeden Wert in jeder Spalte, daher ist der deklarierte Typ nur ein Hinweis: Jede Spalte bekommt den Typ, in den alle ihre Werte passen, und eine Spalte mit gemischten Werten behält deren Text.

  • BOOLEAN, BOOL

    NUMBER(1) mit einem CHECK auf 0 und 1

    Wenn jeder Wert 0 oder 1 ist; eine Spalte, die auch andere Werte enthält, behält sie als Zahlen oder Text.

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

    VARCHAR2(n CHAR), wenn jeder Wert passt, sonst CLOB

    SQLite erzwingt keine Länge; eine deklarierte Länge gilt nur, wenn jeder Wert hineinpasst.

  • TEXT and VARCHAR(n) longer than 4000 bytes

    VARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt (750 Zeichen in einem Schlüssel), sonst CLOB

    Ein VARCHAR2 fasst standardmäßig 4000 Bytes, und Oracle kann kein CLOB indizieren, daher behält Text VARCHAR2, wenn seine Werte passen, und wird sonst ein CLOB.

    Berichtszeile: text_as_lob

  • DECIMAL(p,s), NUMERIC

    der exakte Typ, wenn jeder Wert hineinpasst, sonst ein double

    SQLite speichert sie als Ganzzahlen oder doubles; eine deklarierte Genauigkeit gilt nur, wenn die Werte hineinpassen.

  • BLOB, and columns holding bytes

    BLOB

    Bytes bleiben Bytes; Text und Zahlen in derselben Spalte bleiben als ihre Bytes erhalten.

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    DATE oder TIMESTAMP(p), je nachdem, was die Werte enthalten

    Wenn jeder Wert ein Datum oder ein Datum mit Uhrzeit ist; Epoch-Zahlen und anderer Text behalten ihre Werte unverändert.

  • JSON holding JSON text

    CLOB

    Wenn jeder Wert ein JSON-Objekt oder -Array ist.

  • Infinity in REAL columns

    als BINARY_DOUBLE_INFINITY beibehalten

    In Oracle können doubles Unendlich speichern.

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    GENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten ID oder dem Wert aus sqlite_sequence

    Nur eine Spalte, die genau als INTEGER PRIMARY KEY deklariert ist, ist die rowid; jede Zeile behält ihre ID, und der Zähler beginnt nach der höchsten je vergebenen ID.

  • COLLATE NOCASE

    exakter Vergleich

    Oracle vergleicht Text exakt, sofern nicht anders angegeben; NOCASE-Spalten vergleichen nicht mehr ohne Groß-/Kleinschreibung.

    Berichtszeile: case_insensitive_collation

  • generated columns

    virtuelle Spalten

    Oracle berechnet generierte Spalten nur beim Lesen; STORED-Spalten werden virtuell, mit denselben Werten.

    Berichtszeile: stored_as_virtual

  • generated columns with functions IntoSQL doesn't write, and the || operator

    eine normale Spalte

    Eine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; der Dump enthält keine Werte für generierte Spalten.

    Berichtszeile: generated_not_translated

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

    kein Standardwert

    Ein Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet; CURRENT_TIMESTAMP und datetime('now') werden geschrieben.

    Berichtszeile: default_not_translated

  • CHECK constraints

    übersetzt

    Dieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile.

  • CHECK constraints with functions IntoSQL doesn't write

    nicht angelegt

    Eine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.

    Berichtszeile: check_skipped

  • partial and expression indexes

    nicht angelegt

    IntoSQL schreibt Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an.

    Berichtszeile: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    nach den Daten, ENABLE NOVALIDATE, dann validiert

    SQLite prüft Fremdschlüssel nur auf Anweisung, daher sind Zeilen ohne Elternzeile häufig: Sie laden, und der Schlüssel bleibt mit einer Warnung ungeprüft, statt das Laden abzubrechen.

  • ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT

    entfernt

    Fremdschlüssel in Oracle handeln nur beim Löschen, mit CASCADE oder SET NULL.

    Berichtszeile: foreign_key_action_unsupported

  • empty strings and empty blobs

    NULL

    Oracle speichert einen leeren String als NULL, daher wird ein Wert, der ' war, als NULL gelesen. Der Bericht zählt sie pro Spalte.

    Berichtszeile: empty_string_null

  • foreign keys to tables the dump doesn't create

    nicht angelegt

    Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.

    Berichtszeile: foreign_key_skipped

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

    NOT NULL entfernt

    SQLite erlaubt NULL in einem Primärschlüssel, der nicht die rowid ist; die Spalte kann im Ziel nicht NOT NULL sein, sonst würde das Laden abbrechen.

    Berichtszeile: not_null_relaxed

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

    im Bericht aufgeführt

    Ihr Code ist in der eigenen Sprache von SQLite geschrieben, und virtuelle Tabellen brauchen die Module von SQLite; sie werden aufgeführt, damit du sie neu anlegst. Ihre internen Tabellen werden nicht kopiert.

    Berichtszeile: not_converted_objects

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

    Typen aus den Werten gelesen

    Ein Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten, und die Spalten werden nummeriert.

    Berichtszeile: no_schema

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

    NULL

    unistr(), replace(), char() und || werden so ausgewertet, wie die Shell sie schreibt; andere Ausdrücke lassen sich ohne Datenbank nicht auswerten.

    Berichtszeile: expression_value

  • NUL characters in text

    beibehalten

    Die sqlite3-Shell und Python schneiden Text beim Dumpen an einem NUL-Zeichen ab, daher steht nur, was davor kommt, im Dump.

  • text that isn't valid UTF-8

    die fehlerhaften Bytes als Ersatzzeichen

    Dumps schreiben solchen Text als rohe Bytes; das Skript ist UTF-8.

    Berichtszeile: invalid_utf8_replaced

  • text decoded twice (ñ)

    unverändert kopiert

    Der Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.

    Berichtszeile: mojibake_suspected

In SQLiteIn OracleBerichtszeile
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)der Typ, in den jeder Wert der Spalte passtSQLite speichert jeden Wert in jeder Spalte, daher ist der deklarierte Typ nur ein Hinweis: Jede Spalte bekommt den Typ, in den alle ihre Werte passen, und eine Spalte mit gemischten Werten behält deren Text.
BOOLEAN, BOOLNUMBER(1) mit einem CHECK auf 0 und 1Wenn jeder Wert 0 oder 1 ist; eine Spalte, die auch andere Werte enthält, behält sie als Zahlen oder Text.
TEXT, VARCHAR(n), CHAR(n), CLOBVARCHAR2(n CHAR), wenn jeder Wert passt, sonst CLOBSQLite erzwingt keine Länge; eine deklarierte Länge gilt nur, wenn jeder Wert hineinpasst.
TEXT and VARCHAR(n) longer than 4000 bytesVARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt (750 Zeichen in einem Schlüssel), sonst CLOBEin VARCHAR2 fasst standardmäßig 4000 Bytes, und Oracle kann kein CLOB indizieren, daher behält Text VARCHAR2, wenn seine Werte passen, und wird sonst ein CLOB.text_as_lob
DECIMAL(p,s), NUMERICder exakte Typ, wenn jeder Wert hineinpasst, sonst ein doubleSQLite speichert sie als Ganzzahlen oder doubles; eine deklarierte Genauigkeit gilt nur, wenn die Werte hineinpassen.
BLOB, and columns holding bytesBLOBBytes bleiben Bytes; Text und Zahlen in derselben Spalte bleiben als ihre Bytes erhalten.
DATE, DATETIME, TIMESTAMP holding ISO 8601 textDATE oder TIMESTAMP(p), je nachdem, was die Werte enthaltenWenn jeder Wert ein Datum oder ein Datum mit Uhrzeit ist; Epoch-Zahlen und anderer Text behalten ihre Werte unverändert.
JSON holding JSON textCLOBWenn jeder Wert ein JSON-Objekt oder -Array ist.
Infinity in REAL columnsals BINARY_DOUBLE_INFINITY beibehaltenIn Oracle können doubles Unendlich speichern.
INTEGER PRIMARY KEY, AUTOINCREMENTGENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten ID oder dem Wert aus sqlite_sequenceNur eine Spalte, die genau als INTEGER PRIMARY KEY deklariert ist, ist die rowid; jede Zeile behält ihre ID, und der Zähler beginnt nach der höchsten je vergebenen ID.
COLLATE NOCASEexakter VergleichOracle vergleicht Text exakt, sofern nicht anders angegeben; NOCASE-Spalten vergleichen nicht mehr ohne Groß-/Kleinschreibung.case_insensitive_collation
generated columnsvirtuelle SpaltenOracle berechnet generierte Spalten nur beim Lesen; STORED-Spalten werden virtuell, mit denselben Werten.stored_as_virtual
generated columns with functions IntoSQL doesn't write, and the || operatoreine normale SpalteEine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; der Dump enthält keine Werte für generierte Spalten.generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)kein StandardwertEin Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet; CURRENT_TIMESTAMP und datetime('now') werden geschrieben.default_not_translated
CHECK constraintsübersetztDieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile.
CHECK constraints with functions IntoSQL doesn't writenicht angelegtEine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.check_skipped
partial and expression indexesnicht angelegtIntoSQL schreibt Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an.index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)nach den Daten, ENABLE NOVALIDATE, dann validiertSQLite prüft Fremdschlüssel nur auf Anweisung, daher sind Zeilen ohne Elternzeile häufig: Sie laden, und der Schlüssel bleibt mit einer Warnung ungeprüft, statt das Laden abzubrechen.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTentferntFremdschlüssel in Oracle handeln nur beim Löschen, mit CASCADE oder SET NULL.foreign_key_action_unsupported
empty strings and empty blobsNULLOracle speichert einen leeren String als NULL, daher wird ein Wert, der ' war, als NULL gelesen. Der Bericht zählt sie pro Spalte.empty_string_null
foreign keys to tables the dump doesn't createnicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLNOT NULL entferntSQLite erlaubt NULL in einem Primärschlüssel, der nicht die rowid ist; die Spalte kann im Ziel nicht NOT NULL sein, sonst würde das Laden abbrechen.not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)im Bericht aufgeführtIhr Code ist in der eigenen Sprache von SQLite geschrieben, und virtuelle Tabellen brauchen die Module von SQLite; sie werden aufgeführt, damit du sie neu anlegst. Ihre internen Tabellen werden nicht kopiert.not_converted_objects
dumps without CREATE TABLE (--data-only)Typen aus den Werten gelesenEin Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten, und die Spalten werden nummeriert.no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr(), replace(), char() und || werden so ausgewertet, wie die Shell sie schreibt; andere Ausdrücke lassen sich ohne Datenbank nicht auswerten.expression_value
NUL characters in textbeibehaltenDie sqlite3-Shell und Python schneiden Text beim Dumpen an einem NUL-Zeichen ab, daher steht nur, was davor kommt, im Dump.
text that isn't valid UTF-8die fehlerhaften Bytes als ErsatzzeichenDumps schreiben solchen Text als rohe Bytes; das Skript ist UTF-8.invalid_utf8_replaced
text decoded twice (ñ)unverändert kopiertDer Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.mojibake_suspected

Das Skript in Oracle laden

Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.

NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @sqlite.oracle.sql

Fremdschlüssel werden mit ENABLE NOVALIDATE hinzugefügt, sodass neue Zeilen sofort geprüft werden, und dann validiert. Verweist eine alte Zeile auf eine nicht vorhandene Zeile, nennt das Skript den Fremdschlüssel und lässt ihn unvalidiert, statt auf halbem Weg abzubrechen.

Führe bei einem großen Dump SQL*Plus auf dem Rechner der Datenbank aus. Das Skript schreibt alle 100 Zeilen fest. Der ausführende Benutzer braucht CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER und CREATE PROCEDURE sowie Quota auf seinem Tablespace.

Den SQLite-Dump für das beste Ergebnis erstellen

Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:

  • Die Datenbankdatei selbst wird unverändert konvertiert und Seite für Seite in deinem Browser gelesen. Schließe zuerst die App, die in sie schreibt, damit keine Änderung in ihrer -wal-Datei zurückbleibt.
  • sqlite3 app.db .dump > app.sql schreibt dieselbe Datenbank als SQL, das sich ebenfalls konvertieren lässt, als .sql oder .sql.gz.
  • DB Browser for SQLite schreibt dieses SQL mit File, Export, Database to SQL file, und iterdump() in Python ebenso.

Was nicht konvertiert wird

Sichten und Trigger sind in der eigenen Sprache von SQLite geschrieben. Sie stehen mit Namen im Bericht und werden nie stillschweigend weggelassen, damit du sie für Oracle neu schreiben kannst. Virtuelle Tabellen wie FTS5 und R*Tree werden ebenfalls aufgeführt, und ihre Schattentabellen werden weggelassen.

Fragen zu SQLite zu Oracle

Keine Antwort gefunden? Schreib uns über die Kontaktseite, und ein Mensch antwortet. Kontaktseite

Wird mein Dump hochgeladen?

Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.

Wie groß darf der Dump sein?

Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.

Kann ich die .db-Datei selbst konvertieren?

Ja. Leg die .db-, .sqlite- oder .sqlite3-Datei ab: Sie wird in deinem Browser gelesen und nie hochgeladen. Text mit NUL-Zeichen und jede Ziffer eines double kommen so an, wie sie gespeichert sind, was ein .dump abschneiden kann.

Aus welchen SQLite-Versionen kann der Dump stammen?

Datenbankdateien ab SQLite 3.0, in UTF-8 oder UTF-16, und Dumps aus .dump der sqlite3-Shell oder aus iterdump() in Python. Jede Testdatei und jeder Test-Dump stammt aus sqlite3 3.31 bis 3.54, einschließlich STRICT- und WITHOUT ROWID-Tabellen, und wird Zelle für Zelle mit seiner Quelle verglichen.

Wie werden Spaltentypen bestimmt, wenn SQLite sie nicht erzwingt?

Der deklarierte Typ ist ein Hinweis, und die Werte entscheiden: Eine Spalte wird NUMBER, BINARY_DOUBLE, DATE, TIMESTAMP, BLOB, VARCHAR2 oder CLOB, wenn jeder Wert hineinpasst. Leere Strings werden NULL, wie Oracle sie speichert, und der Bericht zählt sie.

Bleiben INTEGER PRIMARY KEY und AUTOINCREMENT erhalten?

Ja. Ein INTEGER PRIMARY KEY wird eine Identity-Spalte, jede Zeile behält ihre ID, und die nächste ID macht nach der höchsten weiter oder, mit AUTOINCREMENT, nach dem Wert aus sqlite_sequence.

Was ist mit Sichten und Triggern?

Sie stehen mit Namen im Bericht und werden nicht konvertiert, weil jede Datenbank sie in ihrer eigenen Sprache schreibt.

Auf welchen Oracle-Versionen lädt das Skript?

Oracle 19c und neuer. Jeder Test-Dump lädt auf 21c und 23ai und hält beim ersten Fehler an, falls etwas schiefgeht.