Naar de inhoud
IntoSQL-startpagina

PostgreSQL omzetten naar Oracle

Zet een gewone dump van pg_dump of pg_dumpall neer, als .sql of .sql.gz, en download een Oracle-script met dezelfde tabellen, sleutels, indexen en data. Elke waarde die Oracle niet ongewijzigd kan bevatten, en elk object dat het niet overneemt, staat in het rapport.

Je bestand
sqlshop_2024_postgres.sqlVoorbeeldbestand, 6,2 kB
Je database

18 rijen geconverteerd, 2 correcties, geen afgewezen

Tonen

Tabellen in shop_2024_postgres.sqlPostgreSQL 18.6-dump · geschreven door pg_dump · utf8mb4

  • customersgeschreven als CUSTOMERS8 rijen1
    8 kolommen
    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
  • ordersgeschreven als ORDERS10 rijen1
    10 kolommen
    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)

Niet geconverteerd

  • Weergave paid_orders

Elke database schrijft deze in een eigen taal. Herschrijf ze voor 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;

Correcties

  1. "tags" van customers is text[], wat Oracle niet heeft, dus het is CLOB met dezelfde waarden.
  2. "delivery" van orders is interval, wat Oracle niet heeft, dus het is VARCHAR2(100 CHAR) met dezelfde waarden.

Na te kijken

  • 1 weergave, trigger, routine of gebeurtenis is niet geconverteerd; het rapport noemt ze allemaal. Maak ze met de hand opnieuw aan in Oracle.
  • De standaardwaarde van "tags" in customers kan niet voor Oracle worden geschreven (a value its type can't hold), dus de kolom heeft geen standaardwaarde. Voeg de standaardwaarde met de hand toe als nieuwe rijen die nodig hebben.
  • De index idx_orders_details op orders gebruikt een expressie die niet voor Oracle kan worden geschreven (a gin index), dus hij wordt niet aangemaakt. Maak de index met de hand aan als query's hem nodig hebben.
  • 1 waarde in "shipped_at" van orders is een datum die Oracle niet kan opslaan, zoals infinity, dus die is NULL. Oracle slaat jaren 1 tot en met 9999 op, zonder oneindig; vervang die datums in de bron als ze ertoe doen.

Je bestand wordt op deze computer omgezet en nooit geüpload.

Andere voorbeelden:

Wat er verandert van PostgreSQL naar Oracle

Elke rij is een regel die de converter toepast, met de rapportregel die hij schrijft als de regel iets in je data verandert.

  • boolean

    NUMBER(1) met een CHECK op 0 en 1

    Oracle 21c heeft geen boolean-kolomtype; 1 en 0 bewaren true en false op elke versie.

  • varchar(n), char(n)

    VARCHAR2(n CHAR), in tekens geteld

    Lengtes tellen tekens, zoals in PostgreSQL.

  • text

    VARCHAR2(4000 CHAR) als elke waarde in 4000 bytes past (750 tekens in een sleutel), anders CLOB

    Een VARCHAR2 bevat standaard 4000 bytes en Oracle kan een CLOB niet indexeren, dus tekst blijft VARCHAR2 als de waarden passen en wordt CLOB als ze dat niet doen.

    Rapportregel: text_as_lob

  • empty strings and empty bytea values

    NULL

    Oracle slaat een lege string op als NULL, dus een waarde die ' was, wordt teruggelezen als NULL. Het rapport telt ze per kolom.

    Rapportregel: empty_string_null

  • citext

    exacte vergelijking

    Oracle vergelijkt tekst exact, tenzij anders aangegeven, zoals text in PostgreSQL; citext-kolommen negeren hoofdletters niet langer.

    Rapportregel: case_insensitive_collation

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

    NUMBER als de waarden in 38 cijfers passen, anders VARCHAR2

    NUMBER in Oracle bevat 38 cijfers op elke schaal. Bredere getallen blijven tekst, zodat elk cijfer exact blijft.

    Rapportregel: decimal_as_text

  • money

    NUMBER(19,2)

    Oracle heeft geen money-type. Het bedrag blijft een getal, zonder het valutasymbool dat de locale van de server toevoegde.

    Rapportregel: type_replaced

  • interval

    VARCHAR2(100 CHAR) met de tekst van PostgreSQL

    Een interval mengt maanden met dagen en seconden, die Oracle in twee verschillende typen bewaart; de tekst behoudt elk deel.

    Rapportregel: type_replaced

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

    CLOB met een JSON-array

    Oracle heeft geen arrays. Een JSON-array behoudt elk element en NULL, en JSON_TABLE leest hem.

    Rapportregel: type_replaced

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

    VARCHAR2 of CLOB met de tekst van PostgreSQL

    Oracle heeft geen gelijkwaardig type, dus elke waarde behoudt de tekst die PostgreSQL schreef.

    Rapportregel: type_replaced

  • json, jsonb

    CLOB

    De JSON-functies van Oracle lezen JSON uit tekst op elke versie, en een CLOB bewaart waarden van elke grootte.

  • timestamp

    TIMESTAMP

    Een timestamp zonder tijdzone is een kloktijd, net als TIMESTAMP in Oracle. date wordt DATE, dat ook een tijdstip bevat dat op middernacht blijft.

  • timestamp with time zone

    TIMESTAMP WITH TIME ZONE in UTC

    Elke waarde wordt in UTC geschreven: hetzelfde moment, welke offset de dump ook schreef.

  • time

    INTERVAL DAY TO SECOND vanaf middernacht

    Oracle heeft geen type voor een tijdstip; een interval vanaf middernacht bevat elke waarde, 24:00:00 inbegrepen.

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

    NULL

    Het script schrijft jaren 1 tot en met 9999, en Oracle kent geen oneindig. Die waarden worden NULL en het rapport telt ze.

    Rapportregel: date_out_of_range

  • NaN and Infinity in numeric

    NULL

    NUMBER in Oracle kent geen NaN of Infinity, dus die waarden worden NULL en het rapport telt ze.

    Rapportregel: invalid_value_null

  • NOT NULL columns with values that become NULL

    NOT NULL weggelaten

    Een kolom waarvan waarden NULL moesten worden, kan NOT NULL niet houden, anders zou het laden stoppen.

    Rapportregel: not_null_relaxed

  • enum types

    VARCHAR2 met een CHECK op de labels

    Tekst met een check houdt dezelfde waarden.

  • enum columns holding values outside their labels

    VARCHAR2 zonder check

    Waarden die niet bij de labels horen, zouden de check laten mislukken, dus de check wordt niet aangemaakt.

    Rapportregel: enum_check_skipped

  • uuid, inet, cidr, macaddr

    VARCHAR2

    Oracle heeft zulke typen niet; de tekst behoudt elke waarde.

  • bytea

    BLOB

    Bytes blijven bytes.

  • bit(n), bit varying

    NUMBER met de waarde van de bits tot 63 bits; daarboven tekstcijfers

    Bitstrings worden opgeslagen als het getal dat hun bits vormen.

  • oid, xid, cid

    NUMBER(10) met een CHECK dat het niet negatief is

    NUMBER bevat elke waarde.

  • serial, identity

    GENERATED BY DEFAULT ON NULL AS IDENTITY, verdergaand na het hoogste id

    De gekopieerde id's laden ongewijzigd, en de teller gaat verder na het hoogste of na de volgende waarde van de sequence, welke hoger is.

  • a second serial or identity column in a table

    een geheel getal zonder teller

    Oracle telt één identity-kolom per tabel; elke andere behoudt zijn waarden zonder teller.

    Rapportregel: counter_dropped

  • sequences not owned by a column

    CREATE SEQUENCE, op de waarde die hij had bereikt

    Sequences in Oracle werken op dezelfde manier.

  • generated columns

    virtuele kolommen

    Oracle berekent gegenereerde kolommen alleen bij het lezen; STORED-kolommen worden virtueel met dezelfde waarden.

    Rapportregel: stored_as_virtual

  • generated columns with functions Oracle lacks

    een gewone kolom met de waarden

    Een formule die niet voor Oracle kan worden geschreven, levert een gewone kolom met de waarden uit de dump en een regel in het rapport op.

    Rapportregel: generated_not_translated

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

    geen standaardwaarde

    Een standaardwaarde die niet voor Oracle kan worden geschreven, wordt weggelaten en gemeld.

    Rapportregel: default_not_translated

  • CHECK constraints

    vertaald, inline in CREATE TABLE

    Inline checks worden getest terwijl elke rij laadt.

  • CHECK constraints with functions Oracle lacks

    niet aangemaakt

    Een check die niet voor Oracle kan worden geschreven, wordt weggelaten en gemeld.

    Rapportregel: check_skipped

  • CHECK ... NOT VALID

    niet aangemaakt

    PostgreSQL heeft de rijen die er al waren nooit gecontroleerd, dus ze kunnen hem schenden.

    Rapportregel: check_not_valid

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

    niet aangemaakt

    IntoSQL schrijft voor Oracle b-tree-indexen op kolommen, en Oracle kan een CLOB niet indexeren; maak de andere na het laden opnieuw aan.

    Rapportregel: index_skipped

  • foreign keys

    na de data ENABLE NOVALIDATE, daarna gevalideerd met een waarschuwing bij wezen

    De sleutel controleert nieuwe rijen meteen en wordt als laatste gevalideerd; rijen zonder ouder laten hem ongevalideerd met een waarschuwing, in plaats van het laden te stoppen.

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

    weggelaten

    Refererende sleutels in Oracle werken alleen bij verwijderen, met CASCADE of SET NULL.

    Rapportregel: foreign_key_action_unsupported

  • foreign keys to tables the dump doesn't create

    niet aangemaakt

    Een sleutel kan niet verwijzen naar een tabel die er niet is.

    Rapportregel: foreign_key_skipped

  • names over 128 bytes

    ingekort

    Namen in Oracle 12.2 en later bevatten 128 bytes, meer dan de 63 van PostgreSQL.

    Rapportregel: name_shortened

  • partitioned tables

    één tabel met de rijen van elke partitie

    De rijen zijn dezelfde; partitioneer de tabel opnieuw in Oracle als dat nodig is.

    Rapportregel: partitions_dropped

  • schemas

    één schema, tabellen met de naam van hun schema ervoor

    Het script laadt in het schema van de gebruiker die het uitvoert, dus tabellen uit verschillende schema's krijgen de naam van hun schema ervoor; tabellen in public behouden hun naam.

    Rapportregel: schemas_merged

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

    vermeld in het rapport

    Hun code is geschreven in de taal van PostgreSQL, dus ze worden vermeld zodat je ze opnieuw kunt maken.

    Rapportregel: not_converted_objects

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

    typen afgeleid uit de waarden

    Een dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden.

    Rapportregel: no_schema

  • expressions in INSERT values

    NULL

    Een converter die geen database draait, kan ze niet evalueren.

    Rapportregel: expression_value

  • types IntoSQL doesn't know

    CLOB

    Tekst kan elke waarde bevatten; wijzig het type na het laden.

    Rapportregel: unknown_type

  • text that isn't valid in its encoding

    de foute bytes als het vervangingsteken

    Het script is UTF-8 en laadt met NLS_LANG=.AL32UTF8.

    Rapportregel: invalid_utf8_replaced

  • text decoded twice (ñ)

    ongewijzigd gekopieerd

    De dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan.

    Rapportregel: mojibake_suspected

In PostgreSQLIn OracleRapportregel
booleanNUMBER(1) met een CHECK op 0 en 1Oracle 21c heeft geen boolean-kolomtype; 1 en 0 bewaren true en false op elke versie.
varchar(n), char(n)VARCHAR2(n CHAR), in tekens geteldLengtes tellen tekens, zoals in PostgreSQL.
textVARCHAR2(4000 CHAR) als elke waarde in 4000 bytes past (750 tekens in een sleutel), anders CLOBEen VARCHAR2 bevat standaard 4000 bytes en Oracle kan een CLOB niet indexeren, dus tekst blijft VARCHAR2 als de waarden passen en wordt CLOB als ze dat niet doen.text_as_lob
empty strings and empty bytea valuesNULLOracle slaat een lege string op als NULL, dus een waarde die ' was, wordt teruggelezen als NULL. Het rapport telt ze per kolom.empty_string_null
citextexacte vergelijkingOracle vergelijkt tekst exact, tenzij anders aangegeven, zoals text in PostgreSQL; citext-kolommen negeren hoofdletters niet langer.case_insensitive_collation
numeric(p,s) past 38 digits; numeric without a precisionNUMBER als de waarden in 38 cijfers passen, anders VARCHAR2NUMBER in Oracle bevat 38 cijfers op elke schaal. Bredere getallen blijven tekst, zodat elk cijfer exact blijft.decimal_as_text
moneyNUMBER(19,2)Oracle heeft geen money-type. Het bedrag blijft een getal, zonder het valutasymbool dat de locale van de server toevoegde.type_replaced
intervalVARCHAR2(100 CHAR) met de tekst van PostgreSQLEen interval mengt maanden met dagen en seconden, die Oracle in twee verschillende typen bewaart; de tekst behoudt elk deel.type_replaced
arrays (integer[], text[]...)CLOB met een JSON-arrayOracle heeft geen arrays. Een JSON-array behoudt elk element en NULL, en JSON_TABLE leest hem.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesVARCHAR2 of CLOB met de tekst van PostgreSQLOracle heeft geen gelijkwaardig type, dus elke waarde behoudt de tekst die PostgreSQL schreef.type_replaced
json, jsonbCLOBDe JSON-functies van Oracle lezen JSON uit tekst op elke versie, en een CLOB bewaart waarden van elke grootte.
timestampTIMESTAMPEen timestamp zonder tijdzone is een kloktijd, net als TIMESTAMP in Oracle. date wordt DATE, dat ook een tijdstip bevat dat op middernacht blijft.
timestamp with time zoneTIMESTAMP WITH TIME ZONE in UTCElke waarde wordt in UTC geschreven: hetzelfde moment, welke offset de dump ook schreef.
timeINTERVAL DAY TO SECOND vanaf middernachtOracle heeft geen type voor een tijdstip; een interval vanaf middernacht bevat elke waarde, 24:00:00 inbegrepen.
infinity, -infinity, BC dates and years past 9999NULLHet script schrijft jaren 1 tot en met 9999, en Oracle kent geen oneindig. Die waarden worden NULL en het rapport telt ze.date_out_of_range
NaN and Infinity in numericNULLNUMBER in Oracle kent geen NaN of Infinity, dus die waarden worden NULL en het rapport telt ze.invalid_value_null
NOT NULL columns with values that become NULLNOT NULL weggelatenEen kolom waarvan waarden NULL moesten worden, kan NOT NULL niet houden, anders zou het laden stoppen.not_null_relaxed
enum typesVARCHAR2 met een CHECK op de labelsTekst met een check houdt dezelfde waarden.
enum columns holding values outside their labelsVARCHAR2 zonder checkWaarden die niet bij de labels horen, zouden de check laten mislukken, dus de check wordt niet aangemaakt.enum_check_skipped
uuid, inet, cidr, macaddrVARCHAR2Oracle heeft zulke typen niet; de tekst behoudt elke waarde.
byteaBLOBBytes blijven bytes.
bit(n), bit varyingNUMBER met de waarde van de bits tot 63 bits; daarboven tekstcijfersBitstrings worden opgeslagen als het getal dat hun bits vormen.
oid, xid, cidNUMBER(10) met een CHECK dat het niet negatief isNUMBER bevat elke waarde.
serial, identityGENERATED BY DEFAULT ON NULL AS IDENTITY, verdergaand na het hoogste idDe gekopieerde id's laden ongewijzigd, en de teller gaat verder na het hoogste of na de volgende waarde van de sequence, welke hoger is.
a second serial or identity column in a tableeen geheel getal zonder tellerOracle telt één identity-kolom per tabel; elke andere behoudt zijn waarden zonder teller.counter_dropped
sequences not owned by a columnCREATE SEQUENCE, op de waarde die hij had bereiktSequences in Oracle werken op dezelfde manier.
generated columnsvirtuele kolommenOracle berekent gegenereerde kolommen alleen bij het lezen; STORED-kolommen worden virtueel met dezelfde waarden.stored_as_virtual
generated columns with functions Oracle lackseen gewone kolom met de waardenEen formule die niet voor Oracle kan worden geschreven, levert een gewone kolom met de waarden uit de dump en een regel in het rapport op.generated_not_translated
defaults with functions Oracle lacks, and defaults from a sequencegeen standaardwaardeEen standaardwaarde die niet voor Oracle kan worden geschreven, wordt weggelaten en gemeld.default_not_translated
CHECK constraintsvertaald, inline in CREATE TABLEInline checks worden getest terwijl elke rij laadt.
CHECK constraints with functions Oracle lacksniet aangemaaktEen check die niet voor Oracle kan worden geschreven, wordt weggelaten en gemeld.check_skipped
CHECK ... NOT VALIDniet aangemaaktPostgreSQL heeft de rijen die er al waren nooit gecontroleerd, dus ze kunnen hem schenden.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on CLOB columnsniet aangemaaktIntoSQL schrijft voor Oracle b-tree-indexen op kolommen, en Oracle kan een CLOB niet indexeren; maak de andere na het laden opnieuw aan.index_skipped
foreign keysna de data ENABLE NOVALIDATE, daarna gevalideerd met een waarschuwing bij wezenDe sleutel controleert nieuwe rijen meteen en wordt als laatste gevalideerd; rijen zonder ouder laten hem ongevalideerd met een waarschuwing, in plaats van het laden te stoppen.
ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTweggelatenRefererende sleutels in Oracle werken alleen bij verwijderen, met CASCADE of SET NULL.foreign_key_action_unsupported
foreign keys to tables the dump doesn't createniet aangemaaktEen sleutel kan niet verwijzen naar een tabel die er niet is.foreign_key_skipped
names over 128 bytesingekortNamen in Oracle 12.2 en later bevatten 128 bytes, meer dan de 63 van PostgreSQL.name_shortened
partitioned tableséén tabel met de rijen van elke partitieDe rijen zijn dezelfde; partitioneer de tabel opnieuw in Oracle als dat nodig is.partitions_dropped
schemaséén schema, tabellen met de naam van hun schema ervoorHet script laadt in het schema van de gebruiker die het uitvoert, dus tabellen uit verschillende schema's krijgen de naam van hun schema ervoor; tabellen in public behouden hun naam.schemas_merged
views, functions, procedures, triggers, rules, policies, extensions and typesvermeld in het rapportHun code is geschreven in de taal van PostgreSQL, dus ze worden vermeld zodat je ze opnieuw kunt maken.not_converted_objects
dumps without CREATE TABLE (--data-only)typen afgeleid uit de waardenEen dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden.no_schema
expressions in INSERT valuesNULLEen converter die geen database draait, kan ze niet evalueren.expression_value
types IntoSQL doesn't knowCLOBTekst kan elke waarde bevatten; wijzig het type na het laden.unknown_type
text that isn't valid in its encodingde foute bytes als het vervangingstekenHet script is UTF-8 en laadt met NLS_LANG=.AL32UTF8.invalid_utf8_replaced
text decoded twice (ñ)ongewijzigd gekopieerdDe dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan.mojibake_suspected

Het script in Oracle laden

Het script maakt de tabellen aan, kopieert de rijen en voegt daarna sleutels, indexen en refererende sleutels toe, zodat het snel laadt en bij de eerste fout stopt.

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

Refererende sleutels worden toegevoegd met ENABLE NOVALIDATE, zodat nieuwe rijen meteen worden gecontroleerd, en daarna gevalideerd. Verwijst een oude rij naar een rij die niet bestaat, dan vertelt het script welke constraint het is en laat het die ongevalideerd, in plaats van halverwege te mislukken.

Voer bij een grote dump SQL*Plus uit op dezelfde machine als de database. Het script commit elke 100 rijen. De gebruiker die het uitvoert, heeft CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER en CREATE PROCEDURE nodig, en quota op zijn tablespace.

Een dump van PostgreSQL maken voor het beste resultaat

De converter leest wat de dump bevat. Met deze opties blijft er meer van je data in staan:

  • --format=plain, de standaard van pg_dump, schrijft SQL. Een custom- of directoryarchief (-Fc, -Fd) wordt SQL met pg_restore -f dump.sql, zonder databaseserver.
  • --no-owner --no-privileges laten rollen en rechten weg, die de converter toch overslaat, dus de dump wordt kleiner.
  • pg_dumpall zet elke database in één bestand; de tabellen van elke database krijgen de naam ervan, dus niets botst.

Wat niet wordt geconverteerd

Weergaven, gematerialiseerde weergaven, functies, procedures, triggers, regels, beveiligingsbeleid voor rijen, extensies en typen zijn geschreven in de eigen taal van PostgreSQL. Ze staan op naam in het rapport en worden nooit stilletjes weggelaten, zodat je ze kunt herschrijven voor Oracle.

Vragen over PostgreSQL naar Oracle

Staat je vraag er niet bij? Schrijf ons via de contactpagina en een mens antwoordt. Contactpagina

Wordt mijn dump geüpload?

Nee. De converter draait in je browser en leest de dump in delen van je schijf, dus hij verlaat je computer nooit. De desktopapp en de opdrachtregel converteren ook op je computer.

Hoe groot mag de dump zijn?

De converter houdt nooit de hele dump in het geheugen: hij leest het bestand twee keer, in bereiken, en schrijft het script gaandeweg. Dumps van meerdere gigabytes worden geconverteerd in de browser, in de desktopapp en met de opdrachtregel.

Leest het pg_dump -Fc-archieven?

Niet direct: een custom-archief is een binair formaat. pg_restore -f dump.sql dump.backup zet het om naar de gewone SQL die de converter leest, zonder verbinding met een server. De converter meldt dat als hij een archief krijgt.

Van welke PostgreSQL-versies kan de dump komen?

Dumps geschreven door pg_dump en pg_dumpall vanaf PostgreSQL 10, met rijen als COPY of INSERT. Elke testdump komt van PostgreSQL 13 en 18 en wordt cel voor cel met zijn bron vergeleken.

Blijven serial- en identity-waarden behouden?

Ja. De serial- of identity-kolom van elke tabel wordt een identity-kolom, elke rij behoudt zijn id, en het volgende id gaat verder na het hoogste. Sequences die niet bij een kolom horen, worden Oracle-sequences op de waarde die ze hadden bereikt.

Wat gebeurt er met arrays, enums en andere PostgreSQL-typen?

Arrays worden JSON-arrays, booleans NUMBER(1), timestamps met tijdzone TIMESTAMP WITH TIME ZONE, en tekst VARCHAR2 als de waarden passen, anders CLOB. Lege strings worden NULL, zoals Oracle ze opslaat, en het rapport telt ze.

En functies, triggers en weergaven?

Ze staan op naam in het rapport en worden niet geconverteerd, omdat elke database ze in een eigen taal schrijft.

Op welke Oracle-versies laadt het script?

Oracle 19c en later. Elke testdump laadt op 21c en 23ai en stopt bij de eerste fout als er iets misgaat.