Porta un export Oracle su un Oracle più vecchio o più recente
Trascina il file .sql che scrive Database Export di SQL Developer o SQLcl, con le tabelle e le istruzioni Insert, e scarica uno script che si carica su Oracle 19c e successivi. NUMBER, DATE, TIMESTAMP, LOB, identity e sequenze restano come sono, XMLTYPE e JSON conservano il testo in un CLOB, e ogni modifica è elencata nel report.
18 righe convertite, nessuna correzione, nessuna rifiutata
Tabelle in shop_2024_oracle.sqlDump Oracle · scritto da SQL Developer · utf-8
customersscritta come CUSTOMERS8 righe
7 colonne 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 ordersscritta come ORDERS10 righe
9 colonne 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;
Correzioni
Non c'era niente da correggere.
Il tuo file viene convertito su questo computer e non viene mai caricato.
Altri esempi:
Cosa cambia tra il file e lo script
Ogni riga è una regola che il convertitore applica, con la riga del report che scrive quando la regola cambia qualcosa nei tuoi dati.
BOOLEAN (23ai)
BOOLEAN su 23ai, altrimenti NUMBER(1) con un CHECK di 0 e 1
TRUE e FALSE restano true e false.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG
gli stessi tipi, con le loro lunghezze BYTE o CHAR
Gli stessi tipi di testo; LONG diventa CLOB, che ogni versione dalla 8 preferisce.
VARCHAR2 and NVARCHAR2 past what the target's own types hold
VARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte, altrimenti CLOB
Un VARCHAR2 contiene 4000 byte di default e Oracle non può indicizzare un CLOB, quindi il testo resta VARCHAR2 quando i valori ci stanno ed è un CLOB quando no.
Riga del report: text_as_lob
NUMBER, NUMBER(p,s), FLOAT(b)
gli stessi tipi NUMBER
Gli stessi tipi NUMBER e FLOAT, con ogni cifra.
INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND
gli stessi tipi INTERVAL
Gli stessi intervalli.
DATE, TIMESTAMP(p)
DATE e TIMESTAMP(p), come dichiarati
Gli stessi tipi, quindi ogni data mantiene la sua ora al secondo.
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE
gli stessi tipi
Oracle mantiene gli offset da -12:00 a +14:00; un valore con un offset oltre -12:00 è scritto in UTC, lo stesso istante.
JSON (21c), and CLOB holding JSON
JSON su 21c e successive, altrimenti CLOB
Gli stessi valori JSON; un NULL SQL che l'export ha scritto come 'null' resta NULL.
BLOB, RAW(n), LONG RAW
gli stessi tipi; LONG RAW come BLOB
I byte restano byte.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRY
CLOB con il loro testo
XMLTYPE, ROWID e UROWID mantengono il loro testo in un CLOB, quindi lo script si carica su ogni versione dalla 19c.
Riga del report: type_replaced
collations that ignore case (BINARY_CI)
confronto esatto
Le collation delle colonne non vengono scritte, quindi una colonna che ignorava le maiuscole (BINARY_CI) ora distingue Ana da ana.
Riga del report: case_insensitive_collation
identity columns, and a sequence a BEFORE INSERT trigger assigns
GENERATED BY DEFAULT ON NULL AS IDENTITY, che riparte dopo l'id più alto
Gli id copiati si caricano così come sono, e il contatore riparte dopo il più alto. Anche una colonna che un trigger riempie da una sequenza (il metodo prima della 12c) è una identity.
identity columns the target can't count
un intero semplice
Oracle conta una colonna identity per tabella; ogni altra mantiene i suoi valori senza contatore.
Riga del report: counter_dropped
CREATE SEQUENCE
CREATE SEQUENCE con le stesse opzioni
L'export scrive fin dove è arrivata una sequenza come suo START WITH, quindi riparte da lì.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)
colonne virtuali
Le stesse colonne virtuali.
Riga del report: stored_as_virtual
virtual columns with functions IntoSQL doesn't write, and the || operator
una colonna semplice
Una formula che non si può scrivere per Oracle lascia una colonna semplice e una riga nel report; i valori che l'export ha scritto per le colonne virtuali vengono omessi, e Oracle non ne ha nessuno da calcolare.
Riga del report: generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)
nessun valore predefinito
Un valore predefinito che non si può scrivere viene omesso e segnalato.
Riga del report: default_not_translated
CHECK constraints
tradotti
Gli stessi CHECK, verificati mentre ogni riga si carica.
CHECK constraints with functions IntoSQL doesn't write
non creato
Un vincolo CHECK che non si può scrivere viene omesso e segnalato.
Riga del report: check_skipped
CHECK constraints that are DISABLE or ENABLE NOVALIDATE
non creato
Oracle non applica questi vincoli CHECK alle righe già presenti, quindi le righe potrebbero violarli.
Riga del report: check_not_enforced
function-based, bitmap and domain indexes
non creato
IntoSQL scrive indici b-tree su colonne intere; ricrea gli altri dopo il caricamento.
Riga del report: index_skipped
foreign keys
dopo i dati ENABLE NOVALIDATE, poi validata con un avviso sulle righe orfane
La chiave verifica subito le nuove righe e viene validata alla fine; righe senza padre la lasciano non validata con un avviso invece di fermare il caricamento.
ON DELETE CASCADE that cascades in a cycle or along a second path
rimosso
Le chiavi esterne di Oracle agiscono solo in eliminazione, con CASCADE o SET NULL.
Riga del report: foreign_key_action_unsupported
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones
non creato
Una chiave non può riferirsi a una tabella che non c'è, e una che Oracle non verifica può avere righe senza padre.
Riga del report: foreign_key_skipped
names longer than Oracle 12.1 allows
accorciato
Da Oracle 12.2 i nomi contengono 128 byte; un nome più lungo viene accorciato.
Riga del report: name_shortened
partitioned tables
una tabella con le righe di ogni partizione
Le righe sono le stesse; partiziona di nuovo la tabella in Oracle se serve.
Riga del report: partitions_dropped
several schemas in one export
uno schema, tabelle con il nome del loro schema davanti
Lo script si carica nello schema dell'utente che lo esegue, quindi le tabelle di schemi diversi hanno davanti il nome del loro schema; un export di un solo schema mantiene i nomi delle sue tabelle.
Riga del report: schemas_merged
NOT NULL columns with values that become NULL
NOT NULL rimosso
Una colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe.
Riga del report: not_null_relaxed
views, synonyms, types, packages, procedures, functions and other triggers
elencati nel report
Il loro codice è scritto in PL/SQL, quindi vengono elencati perché tu li ricrei.
Riga del report: not_converted_objects
exports without CREATE TABLE (data only)
tipi ricavati dai valori
Un export di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori.
Riga del report: no_schema
expressions in INSERT values other than the ones exports write
NULL
Un convertitore che non esegue un database non può valutarle; to_date, to_timestamp, TO_CLOB, HEXTORAW e le altre che scrivono gli export vengono lette.
Riga del report: expression_value
types IntoSQL doesn't know, and object types
CLOB
Il testo contiene qualsiasi valore; cambia il tipo dopo il caricamento.
Riga del report: unknown_type
dates before year 1 and time zones given as region names
NULL
Un valore che non è una data diventa NULL e il report lo conta.
Riga del report: date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE
NaN e Infinity mantenuti
I tipi a virgola mobile di Oracle contengono NaN e infinito.
NUL characters in text
mantenuto
VARCHAR2 e CLOB possono contenere un carattere NUL, quindi il valore viene copiato così com'è.
text that isn't valid in its encoding
i byte errati come carattere di sostituzione
Lo script è UTF-8 e ogni valore deve essere testo valido.
Riga del report: invalid_utf8_replaced
text decoded twice (ñ)
copiato così com'è
Lo script contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala.
Riga del report: mojibake_suspected
| Nel file | Nello script | Riga del report |
|---|---|---|
| BOOLEAN (23ai) | BOOLEAN su 23ai, altrimenti NUMBER(1) con un CHECK di 0 e 1TRUE e FALSE restano true e false. | |
| VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG | gli stessi tipi, con le loro lunghezze BYTE o CHARGli stessi tipi di testo; LONG diventa CLOB, che ogni versione dalla 8 preferisce. | |
| VARCHAR2 and NVARCHAR2 past what the target's own types hold | VARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte, altrimenti CLOBUn VARCHAR2 contiene 4000 byte di default e Oracle non può indicizzare un CLOB, quindi il testo resta VARCHAR2 quando i valori ci stanno ed è un CLOB quando no. | text_as_lob |
| NUMBER, NUMBER(p,s), FLOAT(b) | gli stessi tipi NUMBERGli stessi tipi NUMBER e FLOAT, con ogni cifra. | |
| INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND | gli stessi tipi INTERVALGli stessi intervalli. | |
| DATE, TIMESTAMP(p) | DATE e TIMESTAMP(p), come dichiaratiGli stessi tipi, quindi ogni data mantiene la sua ora al secondo. | |
| TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE | gli stessi tipiOracle mantiene gli offset da -12:00 a +14:00; un valore con un offset oltre -12:00 è scritto in UTC, lo stesso istante. | |
| JSON (21c), and CLOB holding JSON | JSON su 21c e successive, altrimenti CLOBGli stessi valori JSON; un NULL SQL che l'export ha scritto come 'null' resta NULL. | |
| BLOB, RAW(n), LONG RAW | gli stessi tipi; LONG RAW come BLOBI byte restano byte. | |
| ROWID, UROWID, XMLTYPE, SDO_GEOMETRY | CLOB con il loro testoXMLTYPE, ROWID e UROWID mantengono il loro testo in un CLOB, quindi lo script si carica su ogni versione dalla 19c. | type_replaced |
| collations that ignore case (BINARY_CI) | confronto esattoLe collation delle colonne non vengono scritte, quindi una colonna che ignorava le maiuscole (BINARY_CI) ora distingue Ana da ana. | case_insensitive_collation |
| identity columns, and a sequence a BEFORE INSERT trigger assigns | GENERATED BY DEFAULT ON NULL AS IDENTITY, che riparte dopo l'id più altoGli id copiati si caricano così come sono, e il contatore riparte dopo il più alto. Anche una colonna che un trigger riempie da una sequenza (il metodo prima della 12c) è una identity. | |
| identity columns the target can't count | un intero sempliceOracle conta una colonna identity per tabella; ogni altra mantiene i suoi valori senza contatore. | counter_dropped |
| CREATE SEQUENCE | CREATE SEQUENCE con le stesse opzioniL'export scrive fin dove è arrivata una sequenza come suo START WITH, quindi riparte da lì. | |
| virtual columns (GENERATED ALWAYS AS ... VIRTUAL) | colonne virtualiLe stesse colonne virtuali. | stored_as_virtual |
| virtual columns with functions IntoSQL doesn't write, and the || operator | una colonna sempliceUna formula che non si può scrivere per Oracle lascia una colonna semplice e una riga nel report; i valori che l'export ha scritto per le colonne virtuali vengono omessi, e Oracle non ne ha nessuno da calcolare. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (SYS_GUID(), ||) | nessun valore predefinitoUn valore predefinito che non si può scrivere viene omesso e segnalato. | default_not_translated |
| CHECK constraints | tradottiGli stessi CHECK, verificati mentre ogni riga si carica. | |
| CHECK constraints with functions IntoSQL doesn't write | non creatoUn vincolo CHECK che non si può scrivere viene omesso e segnalato. | check_skipped |
| CHECK constraints that are DISABLE or ENABLE NOVALIDATE | non creatoOracle non applica questi vincoli CHECK alle righe già presenti, quindi le righe potrebbero violarli. | check_not_enforced |
| function-based, bitmap and domain indexes | non creatoIntoSQL scrive indici b-tree su colonne intere; ricrea gli altri dopo il caricamento. | index_skipped |
| foreign keys | dopo i dati ENABLE NOVALIDATE, poi validata con un avviso sulle righe orfaneLa chiave verifica subito le nuove righe e viene validata alla fine; righe senza padre la lasciano non validata con un avviso invece di fermare il caricamento. | |
| ON DELETE CASCADE that cascades in a cycle or along a second path | rimossoLe chiavi esterne di Oracle agiscono solo in eliminazione, con CASCADE o SET NULL. | foreign_key_action_unsupported |
| foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones | non creatoUna chiave non può riferirsi a una tabella che non c'è, e una che Oracle non verifica può avere righe senza padre. | foreign_key_skipped |
| names longer than Oracle 12.1 allows | accorciatoDa Oracle 12.2 i nomi contengono 128 byte; un nome più lungo viene accorciato. | name_shortened |
| partitioned tables | una tabella con le righe di ogni partizioneLe righe sono le stesse; partiziona di nuovo la tabella in Oracle se serve. | partitions_dropped |
| several schemas in one export | uno schema, tabelle con il nome del loro schema davantiLo script si carica nello schema dell'utente che lo esegue, quindi le tabelle di schemi diversi hanno davanti il nome del loro schema; un export di un solo schema mantiene i nomi delle sue tabelle. | schemas_merged |
| NOT NULL columns with values that become NULL | NOT NULL rimossoUna colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe. | not_null_relaxed |
| views, synonyms, types, packages, procedures, functions and other triggers | elencati nel reportIl loro codice è scritto in PL/SQL, quindi vengono elencati perché tu li ricrei. | not_converted_objects |
| exports without CREATE TABLE (data only) | tipi ricavati dai valoriUn export di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori. | no_schema |
| expressions in INSERT values other than the ones exports write | NULLUn convertitore che non esegue un database non può valutarle; to_date, to_timestamp, TO_CLOB, HEXTORAW e le altre che scrivono gli export vengono lette. | expression_value |
| types IntoSQL doesn't know, and object types | CLOBIl testo contiene qualsiasi valore; cambia il tipo dopo il caricamento. | unknown_type |
| dates before year 1 and time zones given as region names | NULLUn valore che non è una data diventa NULL e il report lo conta. | date_out_of_range |
| NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE | NaN e Infinity mantenutiI tipi a virgola mobile di Oracle contengono NaN e infinito. | |
| NUL characters in text | mantenutoVARCHAR2 e CLOB possono contenere un carattere NUL, quindi il valore viene copiato così com'è. | |
| text that isn't valid in its encoding | i byte errati come carattere di sostituzioneLo script è UTF-8 e ogni valore deve essere testo valido. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiato così com'èLo script contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala. | mojibake_suspected |
Carica lo script in Oracle
Lo script crea le tabelle, copia le righe, poi aggiunge chiavi, indici e chiavi esterne, così si carica in fretta e si ferma al primo errore.
NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @oracle.oracle.sqlLe chiavi esterne vengono aggiunte ENABLE NOVALIDATE, così le nuove righe sono controllate subito, e poi validate. Se una riga vecchia punta a una riga che non esiste, lo script dice quale vincolo e lo lascia non validato, invece di fallire a metà.
Per un dump grande, esegui SQL*Plus sulla stessa macchina del database. Lo script fa il commit ogni 100 righe. L'utente che lo esegue ha bisogno di CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER e CREATE PROCEDURE, e di una quota sul suo tablespace.
Fai il dump di Oracle per il miglior risultato
Il convertitore legge ciò che il dump contiene. Con queste opzioni il dump conserva più dei tuoi dati:
- In SQL Developer, scegli Tools, Database Export, con DDL e il formato dati Insert. SQLcl scrive lo stesso con SET SQLFORMAT INSERT.
- Esegui ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS' prima di esportare: il formato di default scrive le date senza ora né secolo.
- Un file .dmp di exp o expdp è binario: importalo in un database Oracle, per esempio Oracle Database Free in Docker, ed esportalo con SQL Developer.
Cosa non viene convertito
Viste, trigger, procedure, funzioni e altri oggetti scritti nel linguaggio di Oracle sono elencati per nome nel report, mai eliminati in silenzio, così puoi verificare ognuno con la versione di Oracle in cui carichi prima di ricrearlo.
Domande sul passaggio di Oracle tra versioni
Non trovi la risposta? Scrivici dalla pagina dei contatti e ti risponde una persona. Pagina dei contatti
Il mio dump viene caricato?
No. Il convertitore funziona nel tuo browser e legge il dump dal tuo disco a pezzi, quindi non lascia mai il tuo computer. Anche l'app desktop e la riga di comando convertono sul tuo computer.
Quanto può essere grande il dump?
Il convertitore non tiene mai l'intero dump in memoria: legge il file due volte, per intervalli, e scrive lo script man mano. I dump di più gigabyte si convertono nel browser, nell'app desktop e con la riga di comando.
Posso convertire un file .dmp di exp o expdp?
Non direttamente: Data Pump e l'Export originale scrivono un formato binario che legge solo Oracle. Importalo in un qualsiasi database Oracle, Oracle Database Free gira in Docker, ed esportalo con Database Export di SQL Developer o con SQLcl. Il convertitore lo segnala quando riceve un file .dmp.
Da quali versioni di Oracle può provenire l'export?
Export di SQL Developer e SQLcl, con le definizioni di tabella di DBMS_METADATA, da Oracle 11g in poi. Ogni export di test viene da Oracle 21c e 23ai, in sessioni americane, tedesche e ISO, ed è confrontato con la sorgente cella per cella.
Cosa succede a NUMBER, DATE e agli altri tipi di Oracle?
Restano come sono: NUMBER con la sua precisione, DATE, TIMESTAMP, gli intervalli, CHAR e VARCHAR2 con le loro lunghezze, RAW e i LOB. XMLTYPE e JSON mantengono il loro testo in un CLOB, quindi lo script si carica su 19c.
Le colonne identity e le sequenze vengono mantenute?
Sì. Le colonne identity e le sequenze restano come sono e ripartono da dove l'export dice che sono arrivate.
E package, procedure e trigger PL/SQL?
Sono elencati per nome nel report e non vengono convertiti, così puoi ricrearli una volta caricate le tabelle.
Su quali versioni di Oracle si carica lo script?
Oracle 19c e successive. Ogni export di test si carica su 21c e 23ai, fermandosi al primo errore se qualcosa va storto.