Aller au contenu
Accueil IntoSQL

Passer un export Oracle vers un Oracle plus ancien ou plus récent

Déposez le fichier .sql qu'écrit Database Export de SQL Developer ou SQLcl, avec ses tables et ses Insert, et téléchargez un script qui se charge sur Oracle 19c et suivants. NUMBER, DATE, TIMESTAMP, les LOB, identités et séquences restent tels quels, XMLTYPE et JSON gardent leur texte dans un CLOB, et chaque changement figure dans le rapport.

Votre fichier
sqlshop_2024_oracle.sqlFichier d'exemple, 9,3 ko
Votre base de données

18 lignes converties, aucune correction, aucune rejetée

Afficher

Tables de shop_2024_oracle.sqlDump Oracle · écrit par SQL Developer · utf-8

  • customersécrite sous le nom CUSTOMERS8 lignes
    7 colonnes
    IDNUMBER(10,0) not null
    NAMEVARCHAR2(100 CHAR) not null
    EMAILVARCHAR2(150 CHAR) not null
    COUNTRYCHAR(2 BYTE) not null
    IS_ACTIVENUMBER(1,0) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) not null
  • ordersécrite sous le nom ORDERS10 lignes
    9 colonnes
    IDNUMBER(10,0) not null
    CUSTOMER_IDNUMBER(10,0) not null
    INVOICENUMBER(10,0)
    STATUSVARCHAR2(10 CHAR) not null
    TOTALNUMBER(10,2) not null
    ITEMSNUMBER(5,0) not null
    ORDERED_ATDATE not null
    SHIPPED_ATDATE
    NOTEVARCHAR2(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;

Corrections

Rien n'avait besoin d'être corrigé.

Votre fichier est converti sur cet ordinateur et n'est jamais envoyé.

Autres exemples :

Ce qui change entre le fichier et le script

Chaque ligne est une règle appliquée par le convertisseur, avec la ligne de rapport qu'il écrit quand la règle change quelque chose dans vos données.

  • BOOLEAN (23ai)

    BOOLEAN sur 23ai, sinon NUMBER(1) avec un CHECK de 0 et 1

    TRUE et FALSE restent true et false.

  • VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG

    les mêmes types, avec leurs longueurs BYTE ou CHAR

    Les mêmes types texte ; LONG devient CLOB, que chaque version depuis la 8 préfère.

  • VARCHAR2 and NVARCHAR2 past what the target's own types hold

    VARCHAR2(4000 CHAR) si chaque valeur tient en 4000 octets, sinon CLOB

    Un VARCHAR2 contient 4000 octets par défaut et Oracle ne peut pas indexer un CLOB ; le texte garde donc VARCHAR2 si ses valeurs y tiennent, sinon il devient CLOB.

    Ligne du rapport: text_as_lob

  • NUMBER, NUMBER(p,s), FLOAT(b)

    les mêmes types NUMBER

    Les mêmes types NUMBER et FLOAT, avec chaque chiffre.

  • INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND

    les mêmes types INTERVAL

    Les mêmes intervalles.

  • DATE, TIMESTAMP(p)

    DATE et TIMESTAMP(p), tels que déclarés

    Les mêmes types ; chaque date garde donc son heure à la seconde près.

  • TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE

    les mêmes types

    Oracle garde les décalages de -12:00 à +14:00 ; une valeur dont le décalage dépasse -12:00 est écrite en UTC, le même instant.

  • JSON (21c), and CLOB holding JSON

    JSON à partir de 21c, sinon CLOB

    Les mêmes valeurs JSON ; un NULL SQL que l'export a écrit 'null' reste NULL.

  • BLOB, RAW(n), LONG RAW

    les mêmes types ; LONG RAW en BLOB

    Les octets restent des octets.

  • ROWID, UROWID, XMLTYPE, SDO_GEOMETRY

    CLOB avec leur texte

    XMLTYPE, ROWID et UROWID gardent leur texte dans un CLOB, pour que le script se charge sur chaque version depuis 19c.

    Ligne du rapport: type_replaced

  • collations that ignore case (BINARY_CI)

    comparaison exacte

    Les collations de colonne ne sont pas écrites ; une colonne insensible à la casse (BINARY_CI) distingue donc maintenant Ana et ana.

    Ligne du rapport: case_insensitive_collation

  • identity columns, and a sequence a BEFORE INSERT trigger assigns

    GENERATED BY DEFAULT ON NULL AS IDENTITY, qui reprend après l'identifiant le plus élevé

    Les identifiants copiés se chargent tels quels, et le compteur reprend après le plus élevé. Une colonne qu'un déclencheur remplit depuis une séquence (la méthode d'avant 12c) devient aussi une colonne d'identité.

  • identity columns the target can't count

    un entier simple

    Oracle compte une colonne d'identité par table ; toute autre garde ses valeurs sans compteur.

    Ligne du rapport: counter_dropped

  • CREATE SEQUENCE

    CREATE SEQUENCE avec les mêmes options

    L'export écrit où en est une séquence comme son START WITH ; elle reprend donc à partir de là.

  • virtual columns (GENERATED ALWAYS AS ... VIRTUAL)

    colonnes virtuelles

    Les mêmes colonnes virtuelles.

    Ligne du rapport: stored_as_virtual

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

    une colonne simple

    Une formule qui ne peut pas être écrite pour Oracle laisse une colonne simple et une ligne dans le rapport ; les valeurs que l'export a écrites pour les colonnes virtuelles sont omises, et Oracle ne peut pas les calculer.

    Ligne du rapport: generated_not_translated

  • defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)

    aucune valeur par défaut

    Une valeur par défaut qui ne peut pas être écrite est omise et signalée.

    Ligne du rapport: default_not_translated

  • CHECK constraints

    traduites

    Les mêmes contraintes CHECK, vérifiées au chargement de chaque ligne.

  • CHECK constraints with functions IntoSQL doesn't write

    non créée

    Une contrainte CHECK qui ne peut pas être écrite est omise et signalée.

    Ligne du rapport: check_skipped

  • CHECK constraints that are DISABLE or ENABLE NOVALIDATE

    non créée

    Oracle n'applique pas ces contraintes CHECK aux lignes déjà présentes, qui peuvent donc les enfreindre.

    Ligne du rapport: check_not_enforced

  • function-based, bitmap and domain indexes

    non créée

    IntoSQL écrit des index b-tree sur des colonnes entières ; recréez les autres après le chargement.

    Ligne du rapport: index_skipped

  • foreign keys

    après les données ENABLE NOVALIDATE, puis validée avec un avertissement sur les orphelins

    La clé vérifie tout de suite les nouvelles lignes et est validée en dernier ; des lignes sans parent la laissent non validée avec un avertissement au lieu d'arrêter le chargement.

  • ON DELETE CASCADE that cascades in a cycle or along a second path

    supprimé

    Les clés étrangères d'Oracle n'agissent qu'à la suppression, avec CASCADE ou SET NULL.

    Ligne du rapport: foreign_key_action_unsupported

  • foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones

    non créée

    Une clé ne peut pas désigner une table absente, et une clé qu'Oracle ne vérifie pas peut avoir des lignes sans parent.

    Ligne du rapport: foreign_key_skipped

  • names longer than Oracle 12.1 allows

    raccourci

    Depuis 12.2, les noms Oracle font 128 octets au plus ; un nom plus long est raccourci.

    Ligne du rapport: name_shortened

  • partitioned tables

    une seule table avec les lignes de chaque partition

    Les lignes sont les mêmes ; partitionnez à nouveau la table dans Oracle si besoin.

    Ligne du rapport: partitions_dropped

  • several schemas in one export

    un seul schéma, tables préfixées par le nom de leur schéma

    Le script se charge dans le schéma de l'utilisateur qui l'exécute ; les tables de schémas différents reçoivent donc le nom de leur schéma en préfixe, et un export d'un seul schéma garde le nom de ses tables.

    Ligne du rapport: schemas_merged

  • NOT NULL columns with values that become NULL

    NOT NULL retiré

    Une colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.

    Ligne du rapport: not_null_relaxed

  • views, synonyms, types, packages, procedures, functions and other triggers

    listés dans le rapport

    Leur code est écrit en PL/SQL ; ils sont donc listés pour que vous les recréiez.

    Ligne du rapport: not_converted_objects

  • exports without CREATE TABLE (data only)

    types déduits des valeurs

    Un export de données seules ne contient que des lignes, donc les types viennent des valeurs.

    Ligne du rapport: no_schema

  • expressions in INSERT values other than the ones exports write

    NULL

    Un convertisseur qui n'exécute pas de base de données ne peut pas les évaluer ; to_date, to_timestamp, TO_CLOB, HEXTORAW et les autres que les exports écrivent sont lus.

    Ligne du rapport: expression_value

  • types IntoSQL doesn't know, and object types

    CLOB

    Le texte contient n'importe quelle valeur ; changez le type après le chargement.

    Ligne du rapport: unknown_type

  • dates before year 1 and time zones given as region names

    NULL

    Une valeur qui n'est pas une date devient NULL et le rapport la compte.

    Ligne du rapport: date_out_of_range

  • NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE

    NaN et Infinity conservés

    Les types à virgule flottante d'Oracle contiennent NaN et l'infini.

  • NUL characters in text

    conservé

    VARCHAR2 et CLOB peuvent contenir un caractère NUL, donc la valeur est copiée telle quelle.

  • text that isn't valid in its encoding

    les octets invalides deviennent le caractère de remplacement

    Le script est en UTF-8 et chaque valeur doit être du texte valide.

    Ligne du rapport: invalid_utf8_replaced

  • text decoded twice (ñ)

    copié tel quel

    Le script contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.

    Ligne du rapport: mojibake_suspected

Dans le fichierDans le scriptLigne du rapport
BOOLEAN (23ai)BOOLEAN sur 23ai, sinon NUMBER(1) avec un CHECK de 0 et 1TRUE et FALSE restent true et false.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONGles mêmes types, avec leurs longueurs BYTE ou CHARLes mêmes types texte ; LONG devient CLOB, que chaque version depuis la 8 préfère.
VARCHAR2 and NVARCHAR2 past what the target's own types holdVARCHAR2(4000 CHAR) si chaque valeur tient en 4000 octets, sinon CLOBUn VARCHAR2 contient 4000 octets par défaut et Oracle ne peut pas indexer un CLOB ; le texte garde donc VARCHAR2 si ses valeurs y tiennent, sinon il devient CLOB.text_as_lob
NUMBER, NUMBER(p,s), FLOAT(b)les mêmes types NUMBERLes mêmes types NUMBER et FLOAT, avec chaque chiffre.
INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECONDles mêmes types INTERVALLes mêmes intervalles.
DATE, TIMESTAMP(p)DATE et TIMESTAMP(p), tels que déclarésLes mêmes types ; chaque date garde donc son heure à la seconde près.
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONEles mêmes typesOracle garde les décalages de -12:00 à +14:00 ; une valeur dont le décalage dépasse -12:00 est écrite en UTC, le même instant.
JSON (21c), and CLOB holding JSONJSON à partir de 21c, sinon CLOBLes mêmes valeurs JSON ; un NULL SQL que l'export a écrit 'null' reste NULL.
BLOB, RAW(n), LONG RAWles mêmes types ; LONG RAW en BLOBLes octets restent des octets.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRYCLOB avec leur texteXMLTYPE, ROWID et UROWID gardent leur texte dans un CLOB, pour que le script se charge sur chaque version depuis 19c.type_replaced
collations that ignore case (BINARY_CI)comparaison exacteLes collations de colonne ne sont pas écrites ; une colonne insensible à la casse (BINARY_CI) distingue donc maintenant Ana et ana.case_insensitive_collation
identity columns, and a sequence a BEFORE INSERT trigger assignsGENERATED BY DEFAULT ON NULL AS IDENTITY, qui reprend après l'identifiant le plus élevéLes identifiants copiés se chargent tels quels, et le compteur reprend après le plus élevé. Une colonne qu'un déclencheur remplit depuis une séquence (la méthode d'avant 12c) devient aussi une colonne d'identité.
identity columns the target can't countun entier simpleOracle compte une colonne d'identité par table ; toute autre garde ses valeurs sans compteur.counter_dropped
CREATE SEQUENCECREATE SEQUENCE avec les mêmes optionsL'export écrit où en est une séquence comme son START WITH ; elle reprend donc à partir de là.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)colonnes virtuellesLes mêmes colonnes virtuelles.stored_as_virtual
virtual columns with functions IntoSQL doesn't write, and the || operatorune colonne simpleUne formule qui ne peut pas être écrite pour Oracle laisse une colonne simple et une ligne dans le rapport ; les valeurs que l'export a écrites pour les colonnes virtuelles sont omises, et Oracle ne peut pas les calculer.generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)aucune valeur par défautUne valeur par défaut qui ne peut pas être écrite est omise et signalée.default_not_translated
CHECK constraintstraduitesLes mêmes contraintes CHECK, vérifiées au chargement de chaque ligne.
CHECK constraints with functions IntoSQL doesn't writenon crééeUne contrainte CHECK qui ne peut pas être écrite est omise et signalée.check_skipped
CHECK constraints that are DISABLE or ENABLE NOVALIDATEnon crééeOracle n'applique pas ces contraintes CHECK aux lignes déjà présentes, qui peuvent donc les enfreindre.check_not_enforced
function-based, bitmap and domain indexesnon crééeIntoSQL écrit des index b-tree sur des colonnes entières ; recréez les autres après le chargement.index_skipped
foreign keysaprès les données ENABLE NOVALIDATE, puis validée avec un avertissement sur les orphelinsLa clé vérifie tout de suite les nouvelles lignes et est validée en dernier ; des lignes sans parent la laissent non validée avec un avertissement au lieu d'arrêter le chargement.
ON DELETE CASCADE that cascades in a cycle or along a second pathsuppriméLes clés étrangères d'Oracle n'agissent qu'à la suppression, avec CASCADE ou SET NULL.foreign_key_action_unsupported
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE onesnon crééeUne clé ne peut pas désigner une table absente, et une clé qu'Oracle ne vérifie pas peut avoir des lignes sans parent.foreign_key_skipped
names longer than Oracle 12.1 allowsraccourciDepuis 12.2, les noms Oracle font 128 octets au plus ; un nom plus long est raccourci.name_shortened
partitioned tablesune seule table avec les lignes de chaque partitionLes lignes sont les mêmes ; partitionnez à nouveau la table dans Oracle si besoin.partitions_dropped
several schemas in one exportun seul schéma, tables préfixées par le nom de leur schémaLe script se charge dans le schéma de l'utilisateur qui l'exécute ; les tables de schémas différents reçoivent donc le nom de leur schéma en préfixe, et un export d'un seul schéma garde le nom de ses tables.schemas_merged
NOT NULL columns with values that become NULLNOT NULL retiréUne colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.not_null_relaxed
views, synonyms, types, packages, procedures, functions and other triggerslistés dans le rapportLeur code est écrit en PL/SQL ; ils sont donc listés pour que vous les recréiez.not_converted_objects
exports without CREATE TABLE (data only)types déduits des valeursUn export de données seules ne contient que des lignes, donc les types viennent des valeurs.no_schema
expressions in INSERT values other than the ones exports writeNULLUn convertisseur qui n'exécute pas de base de données ne peut pas les évaluer ; to_date, to_timestamp, TO_CLOB, HEXTORAW et les autres que les exports écrivent sont lus.expression_value
types IntoSQL doesn't know, and object typesCLOBLe texte contient n'importe quelle valeur ; changez le type après le chargement.unknown_type
dates before year 1 and time zones given as region namesNULLUne valeur qui n'est pas une date devient NULL et le rapport la compte.date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLENaN et Infinity conservésLes types à virgule flottante d'Oracle contiennent NaN et l'infini.
NUL characters in textconservéVARCHAR2 et CLOB peuvent contenir un caractère NUL, donc la valeur est copiée telle quelle.
text that isn't valid in its encodingles octets invalides deviennent le caractère de remplacementLe script est en UTF-8 et chaque valeur doit être du texte valide.invalid_utf8_replaced
text decoded twice (ñ)copié tel quelLe script contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.mojibake_suspected

Charger le script dans Oracle

Le script crée les tables, copie les lignes, puis ajoute les clés, les index et les clés étrangères ; il se charge donc vite et s'arrête à la première erreur.

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

Les clés étrangères sont ajoutées ENABLE NOVALIDATE, donc les nouvelles lignes sont vérifiées tout de suite, puis validées. Si une ancienne ligne pointe vers une ligne qui n'existe pas, le script indique quelle contrainte et la laisse non validée, au lieu d'échouer à mi-chemin.

Pour un gros dump, exécutez SQL*Plus sur la machine de la base de données. Le script valide toutes les 100 lignes. L'utilisateur qui l'exécute a besoin de CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER et CREATE PROCEDURE, et d'un quota sur son tablespace.

Faire le dump Oracle pour un meilleur résultat

Le convertisseur lit ce que contient le dump. Ces options y gardent davantage de vos données :

  • Dans SQL Developer, choisissez Tools, Database Export, avec DDL et le format de données Insert. SQLcl écrit la même chose avec SET SQLFORMAT INSERT.
  • Exécutez ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS' avant l'export : le format par défaut écrit les dates sans leur heure ni leur siècle.
  • Un fichier .dmp de exp ou expdp est binaire : importez-le dans une base Oracle, par exemple Oracle Database Free dans Docker, et exportez-le avec SQL Developer.

Ce qui n'est pas converti

Les vues, triggers, procédures, fonctions et autres objets écrits dans le propre langage de Oracle sont listés par nom dans le rapport, jamais supprimés en silence, pour que vous vérifiiez chacun face à la version de Oracle cible avant de le recréer.

Questions sur le passage de Oracle d'une version à l'autre

Pas de réponse ici ? Écrivez-nous depuis la page de contact, une personne vous répond. Page de contact

Mon dump est-il envoyé ?

Non. Le convertisseur s'exécute dans votre navigateur et lit le dump depuis votre disque par morceaux ; il ne quitte donc jamais votre ordinateur. L'application de bureau et la ligne de commande convertissent aussi sur votre ordinateur.

Quelle taille peut avoir le dump ?

Le convertisseur ne garde jamais tout le dump en mémoire : il lit le fichier deux fois, par plages, et écrit le script au fur et à mesure. Les dumps de plusieurs gigaoctets se convertissent dans le navigateur, dans l'application de bureau et avec la ligne de commande.

Puis-je convertir un fichier .dmp de exp ou expdp ?

Pas directement : Data Pump et l'Export d'origine écrivent un format binaire que seul Oracle lit. Importez-le dans n'importe quelle base Oracle, Oracle Database Free tourne dans Docker, et exportez-le avec Database Export de SQL Developer ou SQLcl. Le convertisseur le signale quand il reçoit un fichier .dmp.

De quelles versions de Oracle l'export peut-il venir ?

Les exports de SQL Developer et SQLcl, avec les définitions de tables de DBMS_METADATA, depuis Oracle 11g. Chaque export de test vient de Oracle 21c et 23ai, dans des sessions américaine, allemande et ISO, et est comparé à sa source cellule par cellule.

Que deviennent NUMBER, DATE et les autres types Oracle ?

Ils restent tels quels : NUMBER avec sa précision, DATE, TIMESTAMP, les intervalles, CHAR et VARCHAR2 avec leurs longueurs, RAW et les LOB. XMLTYPE et JSON gardent leur texte dans un CLOB, pour que le script se charge sur 19c.

Les colonnes d'identité et les séquences sont-elles gardées ?

Oui. Les colonnes d'identité et les séquences restent telles quelles et reprennent là où l'export indique qu'elles en étaient.

Et les packages, procédures et déclencheurs PL/SQL ?

Ils sont listés par nom dans le rapport et ne sont pas convertis, pour que vous puissiez les recréer une fois les tables en place.

Sur quelles versions de Oracle le script se charge-t-il ?

Oracle 19c et versions ultérieures. Chaque export de test se charge sur 21c et 23ai, et s'arrête à la première erreur en cas de problème.