Vai al contenuto
Home di IntoSQL

Converti PostgreSQL in Oracle

Trascina un dump plain di pg_dump o pg_dumpall, come .sql o .sql.gz, e scarica uno script per Oracle con le stesse tabelle, chiavi, indici e dati. Ogni valore che Oracle non può contenere così com'è, e ogni oggetto che non supporta, è elencato nel report.

Il tuo file
sqlshop_2024_postgres.sqlFile di esempio, 6,2 kB
Il tuo database

18 righe convertite, 2 correzioni, nessuna rifiutata

Mostra

Tabelle in shop_2024_postgres.sqlDump PostgreSQL 18.6 · scritto da pg_dump · utf8mb4

  • customersscritta come CUSTOMERS8 righe1
    8 colonne
    IDNUMBER(10) not null
    NAMEVARCHAR2(4000 CHAR) not null
    EMAILVARCHAR2(750 CHAR) not null
    COUNTRYVARCHAR2(2 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    TAGSCLOB not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(6) WITH TIME ZONE not null
  • ordersscritta come ORDERS10 righe1
    10 colonne
    IDNUMBER(10) not null
    CUSTOMER_IDNUMBER(10) not null
    STATUSVARCHAR2(9 CHAR) not null
    TOTALNUMBER(10,2) not null
    ITEMSNUMBER(5) not null
    ORDERED_ATTIMESTAMP(6) not null
    SHIPPED_ATTIMESTAMP(6)
    NOTEVARCHAR2(4000 CHAR)
    DETAILSCLOB
    DELIVERYVARCHAR2(100 CHAR)

Non convertiti

  • Vista paid_orders

Ogni database li scrive nel proprio linguaggio. Riscrivili per Oracle.

-- Written by IntoSQL from a PostgreSQL dump. Load it with: NLS_LANG=.AL32UTF8 sqlplus -S -L <user>/<password>@<database> @<file>
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
SET DEFINE OFF;
SET SQLBLANKLINES ON;
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
CREATE OR REPLACE FUNCTION "INTOSQL_CLOB" (p SYS.ODCIVARCHAR2LIST) RETURN CLOB IS
    r CLOB;
BEGIN
    DBMS_LOB.CREATETEMPORARY(r, TRUE);
    FOR i IN 1 .. p.COUNT LOOP
        IF p(i) IS NOT NULL THEN
            DBMS_LOB.WRITEAPPEND(r, LENGTH2(p(i)), p(i));
        END IF;
    END LOOP;
    RETURN r;
END;
/
CREATE OR REPLACE FUNCTION "INTOSQL_BLOB" (p SYS.ODCIVARCHAR2LIST) RETURN BLOB IS
    r BLOB;
    piece RAW(2000);
BEGIN
    DBMS_LOB.CREATETEMPORARY(r, TRUE);
    FOR i IN 1 .. p.COUNT LOOP
        piece := HEXTORAW(p(i));
        DBMS_LOB.WRITEAPPEND(r, UTL_RAW.LENGTH(piece), piece);
    END LOOP;
    RETURN r;
END;
/

CREATE TABLE "CUSTOMERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1001),
    "NAME" VARCHAR2(4000 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(750 CHAR) NOT NULL,
    "COUNTRY" VARCHAR2(2 CHAR) DEFAULT 'US' NOT NULL,
    "IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
    "TAGS" CLOB NOT NULL,
    "SIGNED_UP" DATE,
    "CREATED_AT" TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1))
);

CREATE TABLE "ORDERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 5001),
    "CUSTOMER_ID" NUMBER(10) NOT NULL,
    "STATUS" VARCHAR2(9 CHAR) DEFAULT 'pending' NOT NULL,
    "TOTAL" NUMBER(10,2) NOT NULL,
    "ITEMS" NUMBER(5) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(6) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(6),
    "NOTE" VARCHAR2(4000 CHAR),
    "DETAILS" CLOB,
    "DELIVERY" VARCHAR2(100 CHAR),
    CONSTRAINT "CK_ORDERS_STATUS" CHECK ("STATUS" IN ('pending', 'paid', 'shipped', 'cancelled')),
    CONSTRAINT "ORDERS_TOTAL_CHECK" CHECK ("TOTAL" >= (0))
);

BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
1,
'Ana Martínez',
'ana@example.com',
'MX',
1,
'["vip"]',
DATE '2023-01-15',
TIMESTAMP '2023-01-15 10:24:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
2,
'Zoë Müller',
'zoe@example.de',
'DE',
1,
'[]',
DATE '2023-02-03',
TIMESTAMP '2023-02-03 08:11:42 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
3,
'José Peña',
'jose@example.es',
'ES',
0,
'["wholesale","late payer"]',
DATE '2023-03-21',
TIMESTAMP '2023-03-21 19:05:17 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
4,
'李雷',
'lilei@example.cn',
'CN',
1,
'[]',
DATE '2023-05-09',
TIMESTAMP '2023-05-09 02:40:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
5,
'Noah O''Brien',
'noah@example.ie',
'IE',
1,
'[]',
NULL,
TIMESTAMP '2023-06-30 14:00:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
6,
'Amélie Laurent',
'amelie@example.fr',
'FR',
1,
'["vip"]',
DATE '2024-01-02',
TIMESTAMP '2024-01-02 09:30:00 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
7,
'Ravi Patel',
'ravi@example.in',
'IN',
0,
'[]',
DATE '2024-02-29',
TIMESTAMP '2024-02-29 23:59:59 +00:00'
);
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"TAGS",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
8,
'Sofia Rossi 🌻',
'sofia@example.it',
'IT',
1,
'[]',
DATE '2024-04-12',
TIMESTAMP '2024-04-12 12:12:12 +00:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
1,
1,
'shipped',
129.90,
3,
TIMESTAMP '2024-03-01 10:00:00',
TIMESTAMP '2024-03-02 16:30:00',
NULL,
'{"gift": false}',
'1 day 06:30:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
2,
2,
'paid',
54.00,
1,
TIMESTAMP '2024-03-02 11:15:00',
NULL,
'Gift wrap 🎁',
'{"gift": true, "wrap": "red"}',
NULL
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
3,
1,
'cancelled',
12.50,
1,
TIMESTAMP '2024-03-03 09:45:00',
NULL,
'Customer changed their mind',
NULL,
NULL
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
4,
4,
'shipped',
980.00,
12,
TIMESTAMP '2024-03-05 02:10:00',
TIMESTAMP '2024-03-07 08:00:00',
'请小心轻放',
'{"fragile": true}',
'2 days 05:50:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
5,
5,
'pending',
45.75,
2,
TIMESTAMP '2024-03-08 17:20:00',
NULL,
'Leave at the door; ring twice',
NULL,
NULL
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
6,
6,
'shipped',
310.40,
5,
TIMESTAMP '2024-03-10 13:00:00',
TIMESTAMP '2024-03-11 09:00:00',
'Fragile: "glass"',
'{"fragile": true}',
'20:00:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
7,
8,
'paid',
76.20,
2,
TIMESTAMP '2024-03-11 18:45:00',
NULL,
NULL,
NULL,
NULL
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
8,
2,
'shipped',
19.99,
1,
TIMESTAMP '2024-03-12 08:00:00',
NULL,
'Shipped date set to infinity by an old import',
NULL,
NULL
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
9,
3,
'shipped',
64.00,
2,
TIMESTAMP '2024-03-14 15:30:00',
TIMESTAMP '2024-03-15 10:00:00',
'Two parcels',
'{"parcels": [1, 2]}',
'18:30:00'
);
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"DELIVERY"
) VALUES (
10,
7,
'paid',
1499.00,
1,
TIMESTAMP '2024-03-15 21:05:00',
NULL,
'C:\Users\ravi\invoice.pdf',
NULL,
NULL
);
COMMIT;
END;
/

-- Keys, indexes, foreign keys, counters and triggers, after the rows.
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "UQ_CUSTOMERS_CUSTOMERS_EMAIL_KEY" UNIQUE ("EMAIL");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "PK_CUSTOMERS" PRIMARY KEY ("ID");
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 "ORDERS_CUSTOMER_ID_FKEY" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "ORDERS_CUSTOMER_ID_FKEY"';
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"ORDERS_CUSTOMER_ID_FKEY"' || ' has rows without a parent: it stays unvalidated, and new rows are checked.');
END;
/
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "CUSTOMERS";
    IF next_id < 1001 THEN
        next_id := 1001;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "CUSTOMERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
COMMENT ON TABLE "CUSTOMERS" IS 'People who bought at least once';
DECLARE
    next_id NUMBER;
BEGIN
    SELECT NVL(MAX("ID"), 0) + 1 INTO next_id FROM "ORDERS";
    IF next_id < 5001 THEN
        next_id := 5001;
    END IF;
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" MODIFY ("ID" GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH ' || next_id || '))';
END;
/
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

Correzioni

  1. "tags" di customers è text[], che Oracle non ha, quindi è CLOB con gli stessi valori.
  2. "delivery" di orders è interval, che Oracle non ha, quindi è VARCHAR2(100 CHAR) con gli stessi valori.

Da controllare

  • 1 vista, trigger, routine o evento non è convertito; il report li elenca uno per uno. Ricreali a mano in Oracle.
  • Il valore predefinito di "tags" in customers non si può scrivere per Oracle (a value its type can't hold), quindi la colonna non ha un valore predefinito. Aggiungi a mano il valore predefinito se le nuove righe ne hanno bisogno.
  • L'indice idx_orders_details su orders usa un'espressione che non si può scrivere per Oracle (a gin index), quindi non viene creato. Crea l'indice a mano se le query ne hanno bisogno.
  • 1 valore in "shipped_at" di orders è una data che Oracle non può salvare, come infinity, quindi è NULL. Oracle salva gli anni dall'1 al 9999 senza infinito; sostituisci quelle date nella sorgente se contano.

Il tuo file viene convertito su questo computer e non viene mai caricato.

Altri esempi:

Cosa cambia da PostgreSQL a Oracle

Ogni riga è una regola che il convertitore applica, con la riga del report che scrive quando la regola cambia qualcosa nei tuoi dati.

  • boolean

    NUMBER(1) con un CHECK di 0 e 1

    Oracle 21c non ha un tipo di colonna booleano; 1 e 0 mantengono true e false su ogni versione.

  • varchar(n), char(n)

    VARCHAR2(n CHAR), contando i caratteri

    Le lunghezze contano i caratteri, come quelle di PostgreSQL.

  • text

    VARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte (750 caratteri in una chiave), 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

  • empty strings and empty bytea values

    NULL

    Oracle salva una stringa vuota come NULL, quindi un valore che era ' si rilegge come NULL. Il report li conta per colonna.

    Riga del report: empty_string_null

  • citext

    confronto esatto

    Oracle confronta il testo in modo esatto salvo indicazione diversa, come il text di PostgreSQL; le colonne citext non ignorano più le maiuscole.

    Riga del report: case_insensitive_collation

  • numeric(p,s) past 38 digits; numeric without a precision

    NUMBER quando i valori stanno in 38 cifre, altrimenti VARCHAR2

    Il NUMBER di Oracle contiene 38 cifre con qualsiasi scala. I numeri più ampi restano testo così ogni cifra resta esatta.

    Riga del report: decimal_as_text

  • money

    NUMBER(19,2)

    Oracle non ha un tipo money. L'importo resta un numero, senza il simbolo di valuta aggiunto dal locale del server.

    Riga del report: type_replaced

  • interval

    VARCHAR2(100 CHAR) con il testo di PostgreSQL

    Un interval mescola mesi con giorni e secondi, che Oracle tiene in due tipi diversi; il testo mantiene ogni parte.

    Riga del report: type_replaced

  • arrays (integer[], text[]...)

    CLOB con un array JSON

    Oracle non ha array. Un array JSON mantiene ogni elemento e i NULL, e JSON_TABLE lo legge.

    Riga del report: type_replaced

  • ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types

    VARCHAR2 o CLOB con il testo di PostgreSQL

    Oracle non ha un tipo equivalente, quindi ogni valore mantiene il testo scritto da PostgreSQL.

    Riga del report: type_replaced

  • json, jsonb

    CLOB

    Le funzioni JSON di Oracle leggono il JSON dal testo su ogni versione, e un CLOB mantiene valori di qualsiasi dimensione.

  • timestamp

    TIMESTAMP

    Un timestamp senza fuso orario è l'ora letta su un orologio, come il TIMESTAMP di Oracle. date diventa DATE, che contiene anche un'ora del giorno che resta a mezzanotte.

  • timestamp with time zone

    TIMESTAMP WITH TIME ZONE in UTC

    Ogni valore è scritto in UTC, lo stesso istante qualunque offset abbia scritto il dump.

  • time

    INTERVAL DAY TO SECOND dalla mezzanotte

    Oracle non ha un tipo per l'ora del giorno; un intervallo dalla mezzanotte contiene ogni valore, 24:00:00 incluso.

  • infinity, -infinity, BC dates and years past 9999

    NULL

    Lo script scrive gli anni dall'1 al 9999, e Oracle non ha infinito. Quei valori diventano NULL e il report li conta.

    Riga del report: date_out_of_range

  • NaN and Infinity in numeric

    NULL

    Il NUMBER di Oracle non ha NaN né Infinity, quindi quei valori diventano NULL e il report li conta.

    Riga del report: invalid_value_null

  • 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

  • enum types

    VARCHAR2 con un CHECK delle sue etichette

    Il testo con un vincolo CHECK mantiene gli stessi valori.

  • enum columns holding values outside their labels

    VARCHAR2 senza CHECK

    I valori che le etichette non nominano violerebbero il vincolo CHECK, quindi il vincolo non viene creato.

    Riga del report: enum_check_skipped

  • uuid, inet, cidr, macaddr

    VARCHAR2

    Oracle non ha questi tipi; il testo mantiene ogni valore.

  • bytea

    BLOB

    I byte restano byte.

  • bit(n), bit varying

    NUMBER con il valore dei bit fino a 63 bit; cifre come testo oltre

    Le stringhe di bit sono salvate come il numero formato dai loro bit.

  • oid, xid, cid

    NUMBER(10) con un CHECK che non sia negativo

    NUMBER contiene ogni valore.

  • serial, identity

    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 o dal valore successivo della sequenza, quello maggiore.

  • a second serial or identity column in a table

    un intero semplice

    Oracle conta una colonna identity per tabella; ogni altra mantiene i suoi valori senza contatore.

    Riga del report: counter_dropped

  • sequences not owned by a column

    CREATE SEQUENCE, al valore raggiunto

    Le sequenze di Oracle funzionano allo stesso modo.

  • generated columns

    colonne virtuali

    Oracle calcola le colonne generate solo in lettura; le colonne STORED diventano virtuali con gli stessi valori.

    Riga del report: stored_as_virtual

  • generated columns with functions Oracle lacks

    una colonna semplice con i valori

    Una formula che non si può scrivere per Oracle lascia una colonna semplice con i valori del dump e una riga nel report.

    Riga del report: generated_not_translated

  • defaults with functions Oracle lacks, and defaults from a sequence

    nessun valore predefinito

    Un valore predefinito che non si può scrivere per Oracle viene omesso e segnalato.

    Riga del report: default_not_translated

  • CHECK constraints

    tradotti, dentro CREATE TABLE

    I CHECK nella tabella si verificano mentre ogni riga si carica.

  • CHECK constraints with functions Oracle lacks

    non creato

    Un vincolo CHECK che non si può scrivere per Oracle viene omesso e segnalato.

    Riga del report: check_skipped

  • CHECK ... NOT VALID

    non creato

    PostgreSQL non ha mai verificato le righe che c'erano prima, quindi potrebbero violarlo.

    Riga del report: check_not_valid

  • gin, gist, brin and hash indexes, partial and expression indexes, and indexes on CLOB columns

    non creato

    IntoSQL scrive indici b-tree su colonne per Oracle, che non può indicizzare un CLOB; 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 UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT

    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 dump doesn't create

    non creato

    Una chiave non può riferirsi a una tabella che non c'è.

    Riga del report: foreign_key_skipped

  • names over 128 bytes

    accorciato

    Da Oracle 12.2 i nomi contengono 128 byte, più dei 63 di PostgreSQL.

    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

  • schemas

    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; le tabelle in public mantengono il loro nome.

    Riga del report: schemas_merged

  • views, functions, procedures, triggers, rules, policies, extensions and types

    elencati nel report

    Il loro codice è scritto nel linguaggio di PostgreSQL, quindi vengono elencati perché tu li ricrei.

    Riga del report: not_converted_objects

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

    tipi ricavati dai valori

    Un dump di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori.

    Riga del report: no_schema

  • expressions in INSERT values

    NULL

    Un convertitore che non esegue un database non può valutarle.

    Riga del report: expression_value

  • types IntoSQL doesn't know

    CLOB

    Il testo contiene qualsiasi valore; cambia il tipo dopo il caricamento.

    Riga del report: unknown_type

  • text that isn't valid in its encoding

    i byte errati come carattere di sostituzione

    Lo script è UTF-8 e si carica con NLS_LANG=.AL32UTF8.

    Riga del report: invalid_utf8_replaced

  • text decoded twice (ñ)

    copiato così com'è

    Il dump contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala.

    Riga del report: mojibake_suspected

In PostgreSQLIn OracleRiga del report
booleanNUMBER(1) con un CHECK di 0 e 1Oracle 21c non ha un tipo di colonna booleano; 1 e 0 mantengono true e false su ogni versione.
varchar(n), char(n)VARCHAR2(n CHAR), contando i caratteriLe lunghezze contano i caratteri, come quelle di PostgreSQL.
textVARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte (750 caratteri in una chiave), 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
empty strings and empty bytea valuesNULLOracle salva una stringa vuota come NULL, quindi un valore che era ' si rilegge come NULL. Il report li conta per colonna.empty_string_null
citextconfronto esattoOracle confronta il testo in modo esatto salvo indicazione diversa, come il text di PostgreSQL; le colonne citext non ignorano più le maiuscole.case_insensitive_collation
numeric(p,s) past 38 digits; numeric without a precisionNUMBER quando i valori stanno in 38 cifre, altrimenti VARCHAR2Il NUMBER di Oracle contiene 38 cifre con qualsiasi scala. I numeri più ampi restano testo così ogni cifra resta esatta.decimal_as_text
moneyNUMBER(19,2)Oracle non ha un tipo money. L'importo resta un numero, senza il simbolo di valuta aggiunto dal locale del server.type_replaced
intervalVARCHAR2(100 CHAR) con il testo di PostgreSQLUn interval mescola mesi con giorni e secondi, che Oracle tiene in due tipi diversi; il testo mantiene ogni parte.type_replaced
arrays (integer[], text[]...)CLOB con un array JSONOracle non ha array. Un array JSON mantiene ogni elemento e i NULL, e JSON_TABLE lo legge.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesVARCHAR2 o CLOB con il testo di PostgreSQLOracle non ha un tipo equivalente, quindi ogni valore mantiene il testo scritto da PostgreSQL.type_replaced
json, jsonbCLOBLe funzioni JSON di Oracle leggono il JSON dal testo su ogni versione, e un CLOB mantiene valori di qualsiasi dimensione.
timestampTIMESTAMPUn timestamp senza fuso orario è l'ora letta su un orologio, come il TIMESTAMP di Oracle. date diventa DATE, che contiene anche un'ora del giorno che resta a mezzanotte.
timestamp with time zoneTIMESTAMP WITH TIME ZONE in UTCOgni valore è scritto in UTC, lo stesso istante qualunque offset abbia scritto il dump.
timeINTERVAL DAY TO SECOND dalla mezzanotteOracle non ha un tipo per l'ora del giorno; un intervallo dalla mezzanotte contiene ogni valore, 24:00:00 incluso.
infinity, -infinity, BC dates and years past 9999NULLLo script scrive gli anni dall'1 al 9999, e Oracle non ha infinito. Quei valori diventano NULL e il report li conta.date_out_of_range
NaN and Infinity in numericNULLIl NUMBER di Oracle non ha NaN né Infinity, quindi quei valori diventano NULL e il report li conta.invalid_value_null
NOT NULL columns with values that become NULLNOT NULL rimossoUna colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe.not_null_relaxed
enum typesVARCHAR2 con un CHECK delle sue etichetteIl testo con un vincolo CHECK mantiene gli stessi valori.
enum columns holding values outside their labelsVARCHAR2 senza CHECKI valori che le etichette non nominano violerebbero il vincolo CHECK, quindi il vincolo non viene creato.enum_check_skipped
uuid, inet, cidr, macaddrVARCHAR2Oracle non ha questi tipi; il testo mantiene ogni valore.
byteaBLOBI byte restano byte.
bit(n), bit varyingNUMBER con il valore dei bit fino a 63 bit; cifre come testo oltreLe stringhe di bit sono salvate come il numero formato dai loro bit.
oid, xid, cidNUMBER(10) con un CHECK che non sia negativoNUMBER contiene ogni valore.
serial, identityGENERATED 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 o dal valore successivo della sequenza, quello maggiore.
a second serial or identity column in a tableun intero sempliceOracle conta una colonna identity per tabella; ogni altra mantiene i suoi valori senza contatore.counter_dropped
sequences not owned by a columnCREATE SEQUENCE, al valore raggiuntoLe sequenze di Oracle funzionano allo stesso modo.
generated columnscolonne virtualiOracle calcola le colonne generate solo in lettura; le colonne STORED diventano virtuali con gli stessi valori.stored_as_virtual
generated columns with functions Oracle lacksuna colonna semplice con i valoriUna formula che non si può scrivere per Oracle lascia una colonna semplice con i valori del dump e una riga nel report.generated_not_translated
defaults with functions Oracle lacks, and defaults from a sequencenessun valore predefinitoUn valore predefinito che non si può scrivere per Oracle viene omesso e segnalato.default_not_translated
CHECK constraintstradotti, dentro CREATE TABLEI CHECK nella tabella si verificano mentre ogni riga si carica.
CHECK constraints with functions Oracle lacksnon creatoUn vincolo CHECK che non si può scrivere per Oracle viene omesso e segnalato.check_skipped
CHECK ... NOT VALIDnon creatoPostgreSQL non ha mai verificato le righe che c'erano prima, quindi potrebbero violarlo.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on CLOB columnsnon creatoIntoSQL scrive indici b-tree su colonne per Oracle, che non può indicizzare un CLOB; ricrea gli altri dopo il caricamento.index_skipped
foreign keysdopo 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 UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTrimossoLe chiavi esterne di Oracle agiscono solo in eliminazione, con CASCADE o SET NULL.foreign_key_action_unsupported
foreign keys to tables the dump doesn't createnon creatoUna chiave non può riferirsi a una tabella che non c'è.foreign_key_skipped
names over 128 bytesaccorciatoDa Oracle 12.2 i nomi contengono 128 byte, più dei 63 di PostgreSQL.name_shortened
partitioned tablesuna tabella con le righe di ogni partizioneLe righe sono le stesse; partiziona di nuovo la tabella in Oracle se serve.partitions_dropped
schemasuno 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; le tabelle in public mantengono il loro nome.schemas_merged
views, functions, procedures, triggers, rules, policies, extensions and typeselencati nel reportIl loro codice è scritto nel linguaggio di PostgreSQL, quindi vengono elencati perché tu li ricrei.not_converted_objects
dumps without CREATE TABLE (--data-only)tipi ricavati dai valoriUn dump di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori.no_schema
expressions in INSERT valuesNULLUn convertitore che non esegue un database non può valutarle.expression_value
types IntoSQL doesn't knowCLOBIl testo contiene qualsiasi valore; cambia il tipo dopo il caricamento.unknown_type
text that isn't valid in its encodingi byte errati come carattere di sostituzioneLo script è UTF-8 e si carica con NLS_LANG=.AL32UTF8.invalid_utf8_replaced
text decoded twice (ñ)copiato così com'èIl dump 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 @postgresql.oracle.sql

Le 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 PostgreSQL per il miglior risultato

Il convertitore legge ciò che il dump contiene. Con queste opzioni il dump conserva più dei tuoi dati:

  • --format=plain, il default di pg_dump, scrive SQL. Un archivio custom o directory (-Fc, -Fd) diventa SQL con pg_restore -f dump.sql, senza un server di database.
  • --no-owner --no-privileges escludono ruoli e permessi, che il convertitore comunque salta, così il dump è più piccolo.
  • pg_dumpall esporta ogni database in un solo file; le tabelle di ognuno hanno il suo nome davanti, così niente entra in conflitto.

Cosa non viene convertito

Viste, viste materializzate, funzioni, procedure, trigger, regole, policy di sicurezza a livello di riga, estensioni e tipi sono scritti nel linguaggio di PostgreSQL. Sono elencati per nome nel report, mai rimossi in silenzio, così puoi riscriverli per Oracle.

Domande sulla conversione da PostgreSQL a Oracle

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.

Legge gli archivi pg_dump -Fc?

Non direttamente: un archivio custom è un formato binario. pg_restore -f dump.sql dump.backup lo trasforma nel SQL plain che il convertitore legge, senza connettersi a un server. Il convertitore lo dice quando riceve un archivio.

Da quali versioni di PostgreSQL può provenire il dump?

Dump scritti da pg_dump e pg_dumpall da PostgreSQL 10 in poi, con righe COPY o INSERT. Ogni dump di test viene da PostgreSQL 13 e 18 ed è confrontato con la sorgente cella per cella.

I valori serial e identity vengono mantenuti?

Sì. La colonna serial o identity di ogni tabella diventa una colonna identity, ogni riga mantiene il suo id e l'id successivo riparte dopo il più alto. Le sequenze non legate a una colonna diventano sequenze di Oracle al valore raggiunto.

Cosa succede ad array, enum e altri tipi di PostgreSQL?

Gli array diventano array JSON, i booleani NUMBER(1), i timestamp con fuso orario TIMESTAMP WITH TIME ZONE e il testo VARCHAR2 quando i valori ci stanno, altrimenti CLOB. Le stringhe vuote diventano NULL, come le salva Oracle, e il report le conta.

E funzioni, trigger e viste?

Sono elencati per nome nel report e non vengono convertiti, perché ogni database li scrive nel proprio linguaggio.

Su quali versioni di Oracle si carica lo script?

Oracle 19c e successive. Ogni dump di test si carica su 21c e 23ai, fermandosi al primo errore se qualcosa va storto.