Einen Oracle-Export auf ein älteres oder neueres Oracle bringen
Zieh die .sql-Datei, die Database Export in SQL Developer oder SQLcl schreibt, mit ihren Tabellen und Insert-Anweisungen hierher und lade ein Skript herunter, das auf Oracle ab 19c lädt. NUMBER, DATE, TIMESTAMP, LOBs, Identities und Sequenzen bleiben, wie sie sind, XMLTYPE und JSON behalten ihren Text in einem CLOB, und jede Änderung steht im Bericht.
18 Zeilen konvertiert, keine Korrekturen, keine abgelehnt
Tabellen in shop_2024_oracle.sqlOracle-Dump · erstellt mit SQL Developer · utf-8
customersgeschrieben als CUSTOMERS8 Zeilen
7 Spalten ID NUMBER(10,0) not null NAME VARCHAR2(100 CHAR) not null EMAIL VARCHAR2(150 CHAR) not null COUNTRY CHAR(2 BYTE) not null IS_ACTIVE NUMBER(1,0) not null SIGNED_UP DATE CREATED_AT TIMESTAMP(0) not null ordersgeschrieben als ORDERS10 Zeilen
9 Spalten ID NUMBER(10,0) not null CUSTOMER_ID NUMBER(10,0) not null INVOICE NUMBER(10,0) STATUS VARCHAR2(10 CHAR) not null TOTAL NUMBER(10,2) not null ITEMS NUMBER(5,0) not null ORDERED_AT DATE not null SHIPPED_AT DATE NOTE VARCHAR2(255 CHAR)
-- Written by IntoSQL from a Oracle 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 SEQUENCE "INVOICE_NUMBERS" START WITH 1020 INCREMENT BY 1 MINVALUE 1;
CREATE TABLE "CUSTOMERS" (
"ID" NUMBER(10,0) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
"NAME" VARCHAR2(100 CHAR) NOT NULL,
"EMAIL" VARCHAR2(150 CHAR) NOT NULL,
"COUNTRY" CHAR(2 BYTE) DEFAULT 'US' NOT NULL,
"IS_ACTIVE" NUMBER(1,0) DEFAULT 1 NOT NULL,
"SIGNED_UP" DATE,
"CREATED_AT" TIMESTAMP(0) DEFAULT LOCALTIMESTAMP NOT NULL,
CONSTRAINT "CHECK1" CHECK ("IS_ACTIVE" IN (0, 1))
);
CREATE TABLE "ORDERS" (
"ID" NUMBER(10,0) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
"CUSTOMER_ID" NUMBER(10,0) NOT NULL,
"INVOICE" NUMBER(10,0) DEFAULT ("INVOICE_NUMBERS".NEXTVAL),
"STATUS" VARCHAR2(10 CHAR) DEFAULT 'pending' NOT NULL,
"TOTAL" NUMBER(10,2) NOT NULL,
"ITEMS" NUMBER(5,0) DEFAULT 1 NOT NULL,
"ORDERED_AT" DATE NOT NULL,
"SHIPPED_AT" DATE,
"NOTE" VARCHAR2(255 CHAR),
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,
TIMESTAMP '2023-01-15 00:00:00',
TIMESTAMP '2023-01-15 10:24:00.000000000'
);
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,
TIMESTAMP '2023-02-03 00:00:00',
TIMESTAMP '2023-02-03 08:11:42.000000000'
);
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,
TIMESTAMP '2023-03-21 00:00:00',
TIMESTAMP '2023-03-21 19:05:17.000000000'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
4,
'李雷',
'lilei@example.cn',
'CN',
1,
TIMESTAMP '2023-05-09 00:00:00',
TIMESTAMP '2023-05-09 02:40:00.000000000'
);
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.000000000'
);
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,
TIMESTAMP '2024-01-02 00:00:00',
TIMESTAMP '2024-01-02 09:30:00.000000000'
);
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,
TIMESTAMP '2024-02-29 00:00:00',
TIMESTAMP '2024-02-29 23:59:59.000000000'
);
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,
TIMESTAMP '2024-04-12 00:00:00',
TIMESTAMP '2024-04-12 12:12:12.000000000'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
1,
1,
1000,
'shipped',
129.9,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
2,
2,
1001,
'paid',
54,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
3,
1,
1002,
'cancelled',
12.5,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
4,
4,
1003,
'shipped',
980,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
5,
5,
1004,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door; ring twice'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
6,
6,
1005,
'shipped',
310.4,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
7,
8,
1006,
'paid',
76.2,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
8,
2,
1007,
'paid',
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Paid at the counter'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
9,
3,
1008,
'shipped',
64,
2,
TIMESTAMP '2024-03-14 15:30:00',
NULL,
'Shipping date never recorded'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"INVOICE",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE"
) VALUES (
10,
7,
1009,
'paid',
1499,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf'
);
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_CUSTOMERS_EMAIL_UK" UNIQUE ("EMAIL");
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
CREATE INDEX "IX_ORDERS_ORDERS_STATUS_DATE_IX" ON "ORDERS" ("STATUS", "ORDERED_AT");
ALTER TABLE "ORDERS" ADD CONSTRAINT "ORDERS_CUSTOMER_FK" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "ORDERS_CUSTOMER_FK"';
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"ORDERS_CUSTOMER_FK"' || ' 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 < 1 THEN
next_id := 1;
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 < 1 THEN
next_id := 1;
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.
Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.
Weitere Beispiele:
Was sich zwischen Datei und Skript ändert
Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.
BOOLEAN (23ai)
BOOLEAN auf 23ai, sonst NUMBER(1) mit einem CHECK auf 0 und 1
TRUE und FALSE bleiben true und false.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG
dieselben Typen, mit ihren Längen in BYTE oder CHAR
Dieselben Texttypen; LONG wird CLOB, das jede Version seit 8 bevorzugt.
VARCHAR2 and NVARCHAR2 past what the target's own types hold
VARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt, 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
NUMBER, NUMBER(p,s), FLOAT(b)
dieselben NUMBER-Typen
Dieselben NUMBER- und FLOAT-Typen, mit jeder Stelle.
INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND
dieselben INTERVAL-Typen
Dieselben Intervalle.
DATE, TIMESTAMP(p)
DATE und TIMESTAMP(p), wie deklariert
Dieselben Typen, daher behält jedes Datum seine Uhrzeit auf die Sekunde.
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE
dieselben Typen
Oracle behält Versätze von -12:00 bis +14:00; ein Wert mit einem Versatz jenseits von -12:00 wird in UTC geschrieben, derselbe Zeitpunkt.
JSON (21c), and CLOB holding JSON
JSON ab 21c, sonst CLOB
Dieselben JSON-Werte; ein SQL-NULL, das der Export als 'null' geschrieben hat, bleibt NULL.
BLOB, RAW(n), LONG RAW
dieselben Typen; LONG RAW als BLOB
Bytes bleiben Bytes.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRY
CLOB mit ihrem Text
XMLTYPE, ROWID und UROWID behalten ihren Text in einem CLOB, damit das Skript auf jeder Version ab 19c lädt.
Berichtszeile: type_replaced
collations that ignore case (BINARY_CI)
exakter Vergleich
Spaltenkollationen werden nicht geschrieben, daher unterscheidet eine Spalte, die Groß-/Kleinschreibung ignorierte (BINARY_CI), jetzt Ana und ana.
Berichtszeile: case_insensitive_collation
identity columns, and a sequence a BEFORE INSERT trigger assigns
GENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten ID
Die kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter. Eine Spalte, die ein Trigger aus einer Sequenz füllt (der Weg vor 12c), wird ebenfalls eine Identity-Spalte.
identity columns the target can't count
eine normale Ganzzahl
Oracle zählt eine Identity-Spalte pro Tabelle; jede andere behält ihre Werte ohne Zähler.
Berichtszeile: counter_dropped
CREATE SEQUENCE
CREATE SEQUENCE mit denselben Optionen
Der Export schreibt den Stand einer Sequenz als ihr START WITH, daher macht sie dort weiter.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)
virtuelle Spalten
Dieselben virtuellen Spalten.
Berichtszeile: stored_as_virtual
virtual columns with functions IntoSQL doesn't write, and the || operator
eine normale Spalte
Eine Formel, die sich nicht für Oracle schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; die Werte, die der Export für virtuelle Spalten geschrieben hat, werden weggelassen, und Oracle kann sie nicht berechnen.
Berichtszeile: generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)
kein Standardwert
Ein Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet.
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
CHECK constraints that are DISABLE or ENABLE NOVALIDATE
nicht angelegt
Oracle wendet diese CHECK-Bedingungen nicht auf die bereits vorhandenen Zeilen an, daher können die Zeilen sie verletzen.
Berichtszeile: check_not_enforced
function-based, bitmap and domain indexes
nicht angelegt
IntoSQL schreibt B-Tree-Indizes auf ganzen Spalten; lege die anderen nach dem Laden neu an.
Berichtszeile: index_skipped
foreign keys
nach den Daten, ENABLE NOVALIDATE, dann validiert, mit einer Warnung bei verwaisten Zeilen
Der Schlüssel prüft neue Zeilen sofort und wird zuletzt validiert; Zeilen ohne Elternzeile lassen ihn mit einer Warnung unvalidiert, statt das Laden abzubrechen.
ON DELETE CASCADE that cascades in a cycle or along a second path
entfernt
Fremdschlüssel in Oracle wirken nur beim Löschen, mit CASCADE oder SET NULL.
Berichtszeile: foreign_key_action_unsupported
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones
nicht angelegt
Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt, und einer, den Oracle nicht prüft, kann Zeilen ohne Elternzeile haben.
Berichtszeile: foreign_key_skipped
names longer than Oracle 12.1 allows
gekürzt
Namen fassen in Oracle ab 12.2 128 Bytes; ein längerer Name wird gekürzt.
Berichtszeile: name_shortened
partitioned tables
eine Tabelle mit den Zeilen aller Partitionen
Die Zeilen bleiben dieselben; partitioniere die Tabelle in Oracle neu, wenn nötig.
Berichtszeile: partitions_dropped
several schemas in one export
ein Schema, jede Tabelle mit dem Namen ihres Schemas vorangestellt
Das Skript lädt in das Schema des ausführenden Benutzers, daher bekommen Tabellen verschiedener Schemas den Namen ihres Schemas vorangestellt; ein Export eines einzelnen Schemas behält die Namen seiner Tabellen.
Berichtszeile: schemas_merged
NOT NULL columns with values that become NULL
NOT NULL entfernt
Eine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen.
Berichtszeile: not_null_relaxed
views, synonyms, types, packages, procedures, functions and other triggers
im Bericht aufgeführt
Ihr Code ist in PL/SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst.
Berichtszeile: not_converted_objects
exports without CREATE TABLE (data only)
Typen aus den Werten gelesen
Ein Export nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten.
Berichtszeile: no_schema
expressions in INSERT values other than the ones exports write
NULL
Ein Konverter, der keine Datenbank ausführt, kann sie nicht auswerten; to_date, to_timestamp, TO_CLOB, HEXTORAW und die anderen, die Exporte schreiben, werden gelesen.
Berichtszeile: expression_value
types IntoSQL doesn't know, and object types
CLOB
Text nimmt jeden Wert auf; ändere den Typ nach dem Laden.
Berichtszeile: unknown_type
dates before year 1 and time zones given as region names
NULL
Ein Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn.
Berichtszeile: date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE
NaN und Infinity bleiben erhalten
Gleitkommatypen in Oracle können NaN und Unendlich speichern.
NUL characters in text
beibehalten
VARCHAR2 und CLOB können ein NUL-Zeichen enthalten, daher wird der Wert unverändert kopiert.
text that isn't valid in its encoding
die fehlerhaften Bytes als Ersatzzeichen
Das Skript ist UTF-8, und jeder Wert muss gültiger Text sein.
Berichtszeile: invalid_utf8_replaced
text decoded twice (ñ)
unverändert kopiert
Das Skript enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.
Berichtszeile: mojibake_suspected
| In der Datei | Im Skript | Berichtszeile |
|---|---|---|
| BOOLEAN (23ai) | BOOLEAN auf 23ai, sonst NUMBER(1) mit einem CHECK auf 0 und 1TRUE und FALSE bleiben true und false. | |
| VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG | dieselben Typen, mit ihren Längen in BYTE oder CHARDieselben Texttypen; LONG wird CLOB, das jede Version seit 8 bevorzugt. | |
| VARCHAR2 and NVARCHAR2 past what the target's own types hold | VARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt, 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 |
| NUMBER, NUMBER(p,s), FLOAT(b) | dieselben NUMBER-TypenDieselben NUMBER- und FLOAT-Typen, mit jeder Stelle. | |
| INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND | dieselben INTERVAL-TypenDieselben Intervalle. | |
| DATE, TIMESTAMP(p) | DATE und TIMESTAMP(p), wie deklariertDieselben Typen, daher behält jedes Datum seine Uhrzeit auf die Sekunde. | |
| TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE | dieselben TypenOracle behält Versätze von -12:00 bis +14:00; ein Wert mit einem Versatz jenseits von -12:00 wird in UTC geschrieben, derselbe Zeitpunkt. | |
| JSON (21c), and CLOB holding JSON | JSON ab 21c, sonst CLOBDieselben JSON-Werte; ein SQL-NULL, das der Export als 'null' geschrieben hat, bleibt NULL. | |
| BLOB, RAW(n), LONG RAW | dieselben Typen; LONG RAW als BLOBBytes bleiben Bytes. | |
| ROWID, UROWID, XMLTYPE, SDO_GEOMETRY | CLOB mit ihrem TextXMLTYPE, ROWID und UROWID behalten ihren Text in einem CLOB, damit das Skript auf jeder Version ab 19c lädt. | type_replaced |
| collations that ignore case (BINARY_CI) | exakter VergleichSpaltenkollationen werden nicht geschrieben, daher unterscheidet eine Spalte, die Groß-/Kleinschreibung ignorierte (BINARY_CI), jetzt Ana und ana. | case_insensitive_collation |
| identity columns, and a sequence a BEFORE INSERT trigger assigns | GENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten IDDie kopierten IDs laden unverändert, und der Zähler macht nach der höchsten weiter. Eine Spalte, die ein Trigger aus einer Sequenz füllt (der Weg vor 12c), wird ebenfalls eine Identity-Spalte. | |
| identity columns the target can't count | eine normale GanzzahlOracle zählt eine Identity-Spalte pro Tabelle; jede andere behält ihre Werte ohne Zähler. | counter_dropped |
| CREATE SEQUENCE | CREATE SEQUENCE mit denselben OptionenDer Export schreibt den Stand einer Sequenz als ihr START WITH, daher macht sie dort weiter. | |
| virtual columns (GENERATED ALWAYS AS ... VIRTUAL) | virtuelle SpaltenDieselben virtuellen Spalten. | stored_as_virtual |
| virtual columns with functions IntoSQL doesn't write, and the || operator | eine normale SpalteEine Formel, die sich nicht für Oracle schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; die Werte, die der Export für virtuelle Spalten geschrieben hat, werden weggelassen, und Oracle kann sie nicht berechnen. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (SYS_GUID(), ||) | kein StandardwertEin Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet. | default_not_translated |
| CHECK constraints | übersetztDieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile. | |
| CHECK constraints with functions IntoSQL doesn't write | nicht angelegtEine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet. | check_skipped |
| CHECK constraints that are DISABLE or ENABLE NOVALIDATE | nicht angelegtOracle wendet diese CHECK-Bedingungen nicht auf die bereits vorhandenen Zeilen an, daher können die Zeilen sie verletzen. | check_not_enforced |
| function-based, bitmap and domain indexes | nicht angelegtIntoSQL schreibt B-Tree-Indizes auf ganzen Spalten; lege die anderen nach dem Laden neu an. | index_skipped |
| foreign keys | nach den Daten, ENABLE NOVALIDATE, dann validiert, mit einer Warnung bei verwaisten ZeilenDer Schlüssel prüft neue Zeilen sofort und wird zuletzt validiert; Zeilen ohne Elternzeile lassen ihn mit einer Warnung unvalidiert, statt das Laden abzubrechen. | |
| ON DELETE CASCADE that cascades in a cycle or along a second path | entferntFremdschlüssel in Oracle wirken nur beim Löschen, mit CASCADE oder SET NULL. | foreign_key_action_unsupported |
| foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones | nicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt, und einer, den Oracle nicht prüft, kann Zeilen ohne Elternzeile haben. | foreign_key_skipped |
| names longer than Oracle 12.1 allows | gekürztNamen fassen in Oracle ab 12.2 128 Bytes; ein längerer Name wird gekürzt. | name_shortened |
| partitioned tables | eine Tabelle mit den Zeilen aller PartitionenDie Zeilen bleiben dieselben; partitioniere die Tabelle in Oracle neu, wenn nötig. | partitions_dropped |
| several schemas in one export | ein Schema, jede Tabelle mit dem Namen ihres Schemas vorangestelltDas Skript lädt in das Schema des ausführenden Benutzers, daher bekommen Tabellen verschiedener Schemas den Namen ihres Schemas vorangestellt; ein Export eines einzelnen Schemas behält die Namen seiner Tabellen. | schemas_merged |
| NOT NULL columns with values that become NULL | NOT NULL entferntEine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen. | not_null_relaxed |
| views, synonyms, types, packages, procedures, functions and other triggers | im Bericht aufgeführtIhr Code ist in PL/SQL geschrieben, daher werden sie aufgeführt, damit du sie neu anlegst. | not_converted_objects |
| exports without CREATE TABLE (data only) | Typen aus den Werten gelesenEin Export nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten. | no_schema |
| expressions in INSERT values other than the ones exports write | NULLEin Konverter, der keine Datenbank ausführt, kann sie nicht auswerten; to_date, to_timestamp, TO_CLOB, HEXTORAW und die anderen, die Exporte schreiben, werden gelesen. | expression_value |
| types IntoSQL doesn't know, and object types | CLOBText nimmt jeden Wert auf; ändere den Typ nach dem Laden. | unknown_type |
| dates before year 1 and time zones given as region names | NULLEin Wert, der kein Datum ist, wird NULL, und der Bericht zählt ihn. | date_out_of_range |
| NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE | NaN und Infinity bleiben erhaltenGleitkommatypen in Oracle können NaN und Unendlich speichern. | |
| NUL characters in text | beibehaltenVARCHAR2 und CLOB können ein NUL-Zeichen enthalten, daher wird der Wert unverändert kopiert. | |
| text that isn't valid in its encoding | die fehlerhaften Bytes als ErsatzzeichenDas Skript ist UTF-8, und jeder Wert muss gültiger Text sein. | invalid_utf8_replaced |
| text decoded twice (ñ) | unverändert kopiertDas Skript 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 @oracle.oracle.sqlFremdschlü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 Oracle-Dump für das beste Ergebnis erstellen
Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:
- Wähle in SQL Developer Tools, Database Export, mit DDL und dem Datenformat Insert. SQLcl schreibt dasselbe mit SET SQLFORMAT INSERT.
- Führe vor dem Export ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS' aus: Das Standardformat schreibt Datumswerte ohne Uhrzeit und Jahrhundert.
- Eine .dmp-Datei aus exp oder expdp ist binär: Importiere sie in eine Oracle-Datenbank, zum Beispiel Oracle Database Free in Docker, und exportiere sie mit SQL Developer.
Was nicht konvertiert wird
Views, Trigger, Prozeduren, Funktionen und andere Objekte in der eigenen Sprache von Oracle stehen mit Namen im Bericht und werden nie stillschweigend entfernt, damit du jedes vor dem Neuanlegen mit der Oracle-Version abgleichen kannst, in die du lädst.
Fragen zum Wechsel von Oracle zwischen Versionen
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 eine .dmp-Datei aus exp oder expdp konvertieren?
Nicht direkt: Data Pump und das ursprüngliche Export-Werkzeug schreiben ein binäres Format, das nur Oracle liest. Importiere die Datei in eine beliebige Oracle-Datenbank (Oracle Database Free läuft in Docker) und exportiere sie mit Database Export in SQL Developer oder mit SQLcl. Der Konverter weist darauf hin, wenn er eine .dmp-Datei bekommt.
Aus welchen Oracle-Versionen kann der Export stammen?
Exporte aus SQL Developer und SQLcl, mit den Tabellendefinitionen von DBMS_METADATA, ab Oracle 11g. Jeder Test-Export stammt aus Oracle 21c und 23ai, in amerikanischen, deutschen und ISO-Sitzungen, und wird Zelle für Zelle mit seiner Quelle verglichen.
Was passiert mit NUMBER, DATE und den anderen Oracle-Typen?
Sie bleiben, wie sie sind: NUMBER mit seiner Genauigkeit, DATE, TIMESTAMP, Intervalle, CHAR und VARCHAR2 mit ihren Längen, RAW und die LOBs. XMLTYPE und JSON behalten ihren Text in einem CLOB, damit das Skript auf 19c lädt.
Bleiben Identity-Spalten und Sequenzen erhalten?
Ja. Identity-Spalten und Sequenzen bleiben, wie sie sind, und machen dort weiter, wo sie laut Export angekommen waren.
Was ist mit PL/SQL-Paketen, Prozeduren und Triggern?
Sie stehen mit Namen im Bericht und werden nicht konvertiert, damit du sie neu anlegen kannst, sobald die Tabellen da sind.
Auf welchen Oracle-Versionen lädt das Skript?
Oracle 19c und neuer. Jeder Test-Export lädt auf 21c und 23ai und hält beim ersten Fehler an, falls etwas schiefgeht.