Aller au contenu
Accueil IntoSQL

Convertir SQL Server en Oracle

Déposez le script que Generate Scripts de SSMS écrit avec le schéma et les données, en .sql ou .sql.gz, UTF-16 ou UTF-8, et téléchargez un script Oracle avec les mêmes tables, clés, index et données. Chaque valeur que Oracle ne peut pas contenir telle quelle, et chaque objet qu'il ne reprend pas, est listé dans le rapport.

Votre fichier
sqlshop_2024_sqlserver.sqlFichier d'exemple, 11 ko
Votre base de données

18 lignes converties, 2 corrections, aucune rejetée

Afficher

Tables de shop_2024_sqlserver.sqlDump SQL Server · écrit par SQL Server Management Objects · utf-8

  • ordersécrite sous le nom ORDERS10 lignes1
    11 colonnes
    IDNUMBER(10) not null
    CUSTOMER_IDNUMBER(10) not null
    STATUSVARCHAR2(10 CHAR) not null
    TOTALNUMBER(19,4) not null
    ITEMSNUMBER(3) not null
    ORDERED_ATTIMESTAMP(0) not null
    SHIPPED_ATTIMESTAMP(7)
    NOTECLOB
    DETAILSCLOB
    ORDER_REFVARCHAR2(36 CHAR) not null
    TOTAL_WITH_TAXNUMBER(12,2)
  • customersécrite sous le nom CUSTOMERS8 lignes1
    8 colonnes
    IDNUMBER(10) not null
    NAMEVARCHAR2(100 CHAR) not null
    EMAILVARCHAR2(200 CHAR) not null
    COUNTRYVARCHAR2(2 CHAR) not null
    IS_ACTIVENUMBER(1) not null
    SIGNED_UPDATE
    CREATED_ATTIMESTAMP(0) WITH TIME ZONE not null
    ROW_VERSIONRAW(8)

Non converti

  • Vue paid_orders
  • Déclencheur orders_no_negative

Chaque base de données les écrit dans son propre langage. Réécrivez-les pour Oracle.

-- Written by IntoSQL from a SQL Server 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 "ORDERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
    "CUSTOMER_ID" NUMBER(10) NOT NULL,
    "STATUS" VARCHAR2(10 CHAR) DEFAULT 'pending' NOT NULL,
    "TOTAL" NUMBER(19,4) NOT NULL,
    "ITEMS" NUMBER(3) DEFAULT 1 NOT NULL,
    "ORDERED_AT" TIMESTAMP(0) NOT NULL,
    "SHIPPED_AT" TIMESTAMP(7),
    "NOTE" CLOB,
    "DETAILS" CLOB,
    "ORDER_REF" VARCHAR2(36 CHAR) NOT NULL,
    "TOTAL_WITH_TAX" NUMBER(12,2) GENERATED ALWAYS AS (CAST(CAST("TOTAL" * (1.16) AS NUMBER(12,2)) AS NUMBER(12,2))) VIRTUAL,
    CONSTRAINT "CK_ORDERS_ITEMS" CHECK ("ITEMS" >= 0),
    CONSTRAINT "CHECK2" CHECK ("STATUS" = 'cancelled' OR "STATUS" = 'shipped' OR "STATUS" = 'paid' OR "STATUS" = 'pending'),
    CONSTRAINT "CHECK3" CHECK ("TOTAL" >= (0))
);

CREATE TABLE "CUSTOMERS" (
    "ID" NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
    "NAME" VARCHAR2(100 CHAR) NOT NULL,
    "EMAIL" VARCHAR2(200 CHAR) NOT NULL,
    "COUNTRY" VARCHAR2(2 CHAR) DEFAULT 'US' NOT NULL,
    "IS_ACTIVE" NUMBER(1) DEFAULT 1 NOT NULL,
    "SIGNED_UP" DATE,
    "CREATED_AT" TIMESTAMP(0) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
    "ROW_VERSION" RAW(8),
    CONSTRAINT "CK_CUSTOMERS_IS_ACTIVE" CHECK ("IS_ACTIVE" IN (0, 1))
);

BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
1,
'Ana Martínez',
'ana@example.com',
'MX',
1,
DATE '2023-01-15',
TIMESTAMP '2023-01-15 04:24:00.0000000 -06:00'
);
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,
DATE '2023-02-03',
TIMESTAMP '2023-02-03 09:11:42.0000000 +01:00'
);
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,
DATE '2023-03-21',
TIMESTAMP '2023-03-21 20:05:17.0000000 +01:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "CUSTOMERS" (
"ID",
"NAME",
"EMAIL",
"COUNTRY",
"IS_ACTIVE",
"SIGNED_UP",
"CREATED_AT"
) VALUES (
4,
'李雷',
'lilei@example.cn',
'CN',
1,
DATE '2023-05-09',
TIMESTAMP '2023-05-09 10:40:00.0000000 +08:00'
);
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 15:00:00.0000000 +01:00'
);
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,
DATE '2024-01-02',
TIMESTAMP '2024-01-02 10:30:00.0000000 +01:00'
);
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,
DATE '2024-02-29',
TIMESTAMP '2024-03-01 05:29:59.0000000 +05:30'
);
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,
DATE '2024-04-12',
TIMESTAMP '2024-04-12 14:12:12.0000000 +02:00'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
1,
1,
'shipped',
129.9000,
3,
TIMESTAMP '2024-03-01 10:00:00.0000000',
TIMESTAMP '2024-03-02 16:30:00.1234567',
NULL,
'{"gift": false}',
'0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
2,
2,
'paid',
54.0000,
1,
TIMESTAMP '2024-03-02 11:15:00.0000000',
NULL,
'Gift wrap 🎁',
'{"gift": true, "wrap": "red"}',
'1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
3,
1,
'cancelled',
12.5000,
1,
TIMESTAMP '2024-03-03 09:45:00.0000000',
NULL,
'Customer changed their mind',
NULL,
'2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
4,
4,
'shipped',
980.0000,
12,
TIMESTAMP '2024-03-05 02:10:00.0000000',
TIMESTAMP '2024-03-07 08:00:00.0000000',
'请小心轻放',
'{"fragile": true}',
'3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
5,
5,
'pending',
45.7500,
2,
TIMESTAMP '2024-03-08 17:20:00.0000000',
NULL,
'Leave at the door; ring twice',
NULL,
'4f1e806c-7d5b-4c2e-9a99-5e6f708192a3'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
6,
6,
'shipped',
310.4000,
5,
TIMESTAMP '2024-03-10 13:00:00.0000000',
TIMESTAMP '2024-03-11 09:00:00.0000000',
'Fragile: "glass"',
'{"fragile": true}',
'50f2917d-8e6c-4d3f-8baa-6f708192a3b4'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
7,
8,
'paid',
76.2000,
2,
TIMESTAMP '2024-03-11 18:45:00.0000000',
NULL,
NULL,
NULL,
'6103a28e-9f7d-4e40-9cbb-708192a3b4c5'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
8,
2,
'shipped',
19.9900,
1,
TIMESTAMP '2024-03-12 08:00:00.0000000',
TIMESTAMP '9999-12-31 23:59:59.9999999',
'Shipped date set to the maximum by an old import',
NULL,
'7214b39f-a08e-4f51-8dcc-8192a3b4c5d6'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
9,
3,
'shipped',
64.0000,
2,
TIMESTAMP '2024-03-14 15:30:00.0000000',
TIMESTAMP '2024-03-15 10:00:00.0000000',
'Two parcels',
'{"parcels": [1, 2]}',
'8325c4a0-b19f-4062-9edd-92a3b4c5d6e7'
);
COMMIT;
END;
/
BEGIN
INSERT INTO "ORDERS" (
"ID",
"CUSTOMER_ID",
"STATUS",
"TOTAL",
"ITEMS",
"ORDERED_AT",
"SHIPPED_AT",
"NOTE",
"DETAILS",
"ORDER_REF"
) VALUES (
10,
7,
'paid',
1499.0000,
1,
TIMESTAMP '2024-03-15 21:05:00.0000000',
NULL,
'C:\Users\ravi\invoice.pdf',
NULL,
'9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8'
);
COMMIT;
END;
/

-- Keys, indexes, foreign keys, counters and triggers, after the rows.
ALTER TABLE "ORDERS" ADD CONSTRAINT "PK_ORDERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "PK_CUSTOMERS" PRIMARY KEY ("ID");
ALTER TABLE "CUSTOMERS" ADD CONSTRAINT "UQ_CUSTOMERS_EMAIL" UNIQUE ("EMAIL");
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 "FK_ORDERS" FOREIGN KEY ("CUSTOMER_ID") REFERENCES "CUSTOMERS" ("ID") ENABLE NOVALIDATE;
BEGIN
    EXECUTE IMMEDIATE 'ALTER TABLE "ORDERS" ENABLE VALIDATE CONSTRAINT "FK_ORDERS"';
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Foreign key ' || '"FK_ORDERS"' || ' 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 "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;
/
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';
DROP FUNCTION "INTOSQL_CLOB";
DROP FUNCTION "INTOSQL_BLOB";
COMMIT;
EXIT;

Corrections

  1. "total_with_tax" de orders est stockée dans la source ; Oracle la calcule à la lecture.
  2. "row_version" de customers est une version de ligne que SQL Server définit lui-même ; le dump n'a aucune valeur pour elle, elle est donc en RAW(8) et vide.

À vérifier

  • 6 colonnes de texte comparent sans tenir compte de la casse dans la source ; Oracle compare exactement, donc les clés uniques et les recherches peuvent se comporter autrement. Utilisez une collation ou un type de colonne insensible à la casse sur les colonnes qui en ont besoin.
  • 2 objets non convertis (vues, déclencheurs, routines ou événements) ; le rapport les liste un par un. Recréez-les à la main dans Oracle.
  • La contrainte CHECK check1 sur orders ne peut pas être écrite pour Oracle (function isjson) ; elle n'est donc pas créée. Écrivez la contrainte à la main si elle compte.
  • L'index idx_orders_pending sur orders utilise une expression qui ne peut pas être écrite pour Oracle (filtered index) ; il n'est donc pas créé. Créez l'index à la main si les requêtes en ont besoin.
  • La valeur par défaut de "order_ref" dans orders ne peut pas être écrite pour Oracle (function uuid) ; la colonne n'a donc pas de valeur par défaut. Ajoutez la valeur par défaut à la main si les nouvelles lignes en ont besoin.

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

Autres exemples :

Ce qui change de SQL Server à Oracle

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.

  • bit

    NUMBER(1) avec un CHECK de 0 et 1

    Oracle 21c n'a pas de type de colonne booléen ; 1 et 0 gardent les valeurs sur chaque version.

  • char(n), varchar(n), nchar(n), nvarchar(n)

    VARCHAR2(n CHAR), en caractères

    Les longueurs comptent les caractères, comme le nvarchar de SQL Server.

  • varchar(max), nvarchar(max), text, ntext

    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

  • empty strings and empty binary values

    NULL

    Oracle stocke une chaîne vide comme NULL, donc une valeur qui valait ' se relit comme NULL. Le rapport les compte par colonne.

    Ligne du rapport: empty_string_null

  • decimal(p,s), money, smallmoney

    NUMBER(p,s) ; money en NUMBER(19,4)

    NUMBER contient 38 chiffres, comme decimal, donc chaque valeur est exacte.

  • datetime, datetime2, smalldatetime

    TIMESTAMP(p)

    Un datetime est une date et une heure locales, comme le TIMESTAMP d'Oracle, qui garde jusqu'à neuf chiffres de seconde. date devient DATE, qui contient aussi une heure du jour, laissée à minuit.

  • datetimeoffset

    TIMESTAMP WITH TIME ZONE, avec le décalage de chaque valeur

    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.

  • time

    INTERVAL DAY TO SECOND depuis minuit

    Oracle n'a pas de type heure du jour ; un intervalle depuis minuit contient chaque valeur.

  • dates that aren't valid

    NULL

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

    Ligne du rapport: date_out_of_range

  • json (SQL Server 2025)

    CLOB

    Les mêmes valeurs JSON, que lisent les fonctions JSON d'Oracle.

  • uniqueidentifier

    VARCHAR2(36)

    Les mêmes identifiants, écrits en minuscules.

  • binary, varbinary, image

    RAW(n) et BLOB

    Les octets restent des octets.

  • geometry, geography

    BLOB avec les octets propres à SQL Server

    SSMS écrit les valeurs spatiales dans la sérialisation de SQL Server, qui est gardée octet par octet.

    Ligne du rapport: spatial_as_native

  • rowversion, timestamp

    BLOB, sans valeurs

    SQL Server définit lui-même la version de ligne et SSMS n'écrit aucune valeur pour elle dans le script.

    Ligne du rapport: rowversion_empty

  • xml, sql_variant, hierarchyid, vector

    VARCHAR2 ou CLOB avec le texte de chaque valeur

    Oracle n'a pas de type équivalent ; xml et sql_variant gardent le texte de chaque valeur et hierarchyid son chemin, comme /1/2/.

    Ligne du rapport: type_replaced

  • collations that ignore case (_CI_)

    comparaison exacte

    Oracle compare le texte exactement sauf indication contraire ; les colonnes insensibles à la casse dans SQL Server distinguent donc maintenant Ana et ana.

    Ligne du rapport: case_insensitive_collation

  • IDENTITY

    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é.

  • CREATE SEQUENCE

    CREATE SEQUENCE avec les mêmes options

    Les séquences Oracle fonctionnent de la même façon. SSMS n'écrit pas où en est une séquence, elle repart donc de sa valeur de création.

  • computed columns

    colonnes virtuelles

    Oracle ne calcule les colonnes générées qu'à la lecture ; les colonnes PERSISTED deviennent virtuelles avec les mêmes valeurs.

    Ligne du rapport: stored_as_virtual

  • computed columns with functions Oracle lacks

    une colonne simple

    Une formule qui ne peut pas être écrite laisse une colonne simple et une ligne dans le rapport ; SSMS n'écrit aucune valeur pour les colonnes calculées.

    Ligne du rapport: generated_not_translated

  • defaults with functions Oracle lacks, and NEXT VALUE FOR

    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 Oracle lacks

    non créée

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

    Ligne du rapport: check_skipped

  • CHECK constraints added WITH NOCHECK or disabled

    non créée

    SQL Server n'applique pas ces contraintes CHECK, donc les lignes peuvent les enfreindre.

    Ligne du rapport: check_not_enforced

  • filtered and columnstore indexes, and indexes on CLOB columns

    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 UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT

    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

  • names over 128 bytes

    raccourci

    Depuis Oracle 12.2, les noms contiennent 128 octets ; ceux de SQL Server contiennent 128 caractères.

    Ligne du rapport: name_shortened

  • foreign keys to tables the dump doesn't create

    non créée

    Une clé ne peut pas désigner une table absente.

    Ligne du rapport: foreign_key_skipped

  • tables on a partition scheme

    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

  • temporal tables (SYSTEM_VERSIONING)

    deux tables : les lignes actuelles et l'historique

    La table et sa table d'historique sont copiées comme tables simples ; Oracle ne garde pas l'historique de lui-même.

    Ligne du rapport: system_versioning_dropped

  • schemas

    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 sont donc préfixées par le nom de leur schéma, et celles de dbo gardent leur nom.

    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, functions, procedures, triggers, synonyms, types and partition functions

    listés dans le rapport

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

    Ligne du rapport: not_converted_objects

  • scripts without CREATE TABLE (data only)

    types déduits des valeurs

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

    Ligne du rapport: no_schema

  • expressions in INSERT values

    NULL

    Un convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.

    Ligne du rapport: expression_value

  • types IntoSQL doesn't know

    CLOB

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

    Ligne du rapport: unknown_type

  • 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 SQL ServerDans OracleLigne du rapport
bitNUMBER(1) avec un CHECK de 0 et 1Oracle 21c n'a pas de type de colonne booléen ; 1 et 0 gardent les valeurs sur chaque version.
char(n), varchar(n), nchar(n), nvarchar(n)VARCHAR2(n CHAR), en caractèresLes longueurs comptent les caractères, comme le nvarchar de SQL Server.
varchar(max), nvarchar(max), text, ntextVARCHAR2(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
empty strings and empty binary valuesNULLOracle stocke une chaîne vide comme NULL, donc une valeur qui valait ' se relit comme NULL. Le rapport les compte par colonne.empty_string_null
decimal(p,s), money, smallmoneyNUMBER(p,s) ; money en NUMBER(19,4)NUMBER contient 38 chiffres, comme decimal, donc chaque valeur est exacte.
datetime, datetime2, smalldatetimeTIMESTAMP(p)Un datetime est une date et une heure locales, comme le TIMESTAMP d'Oracle, qui garde jusqu'à neuf chiffres de seconde. date devient DATE, qui contient aussi une heure du jour, laissée à minuit.
datetimeoffsetTIMESTAMP WITH TIME ZONE, avec le décalage de chaque valeurOracle 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.
timeINTERVAL DAY TO SECOND depuis minuitOracle n'a pas de type heure du jour ; un intervalle depuis minuit contient chaque valeur.
dates that aren't validNULLUne valeur qui n'est pas une date devient NULL et le rapport la compte.date_out_of_range
json (SQL Server 2025)CLOBLes mêmes valeurs JSON, que lisent les fonctions JSON d'Oracle.
uniqueidentifierVARCHAR2(36)Les mêmes identifiants, écrits en minuscules.
binary, varbinary, imageRAW(n) et BLOBLes octets restent des octets.
geometry, geographyBLOB avec les octets propres à SQL ServerSSMS écrit les valeurs spatiales dans la sérialisation de SQL Server, qui est gardée octet par octet.spatial_as_native
rowversion, timestampBLOB, sans valeursSQL Server définit lui-même la version de ligne et SSMS n'écrit aucune valeur pour elle dans le script.rowversion_empty
xml, sql_variant, hierarchyid, vectorVARCHAR2 ou CLOB avec le texte de chaque valeurOracle n'a pas de type équivalent ; xml et sql_variant gardent le texte de chaque valeur et hierarchyid son chemin, comme /1/2/.type_replaced
collations that ignore case (_CI_)comparaison exacteOracle compare le texte exactement sauf indication contraire ; les colonnes insensibles à la casse dans SQL Server distinguent donc maintenant Ana et ana.case_insensitive_collation
IDENTITYGENERATED 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é.
CREATE SEQUENCECREATE SEQUENCE avec les mêmes optionsLes séquences Oracle fonctionnent de la même façon. SSMS n'écrit pas où en est une séquence, elle repart donc de sa valeur de création.
computed columnscolonnes virtuellesOracle ne calcule les colonnes générées qu'à la lecture ; les colonnes PERSISTED deviennent virtuelles avec les mêmes valeurs.stored_as_virtual
computed columns with functions Oracle lacksune colonne simpleUne formule qui ne peut pas être écrite laisse une colonne simple et une ligne dans le rapport ; SSMS n'écrit aucune valeur pour les colonnes calculées.generated_not_translated
defaults with functions Oracle lacks, and NEXT VALUE FORaucune 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 Oracle lacksnon crééeUne contrainte CHECK qui ne peut pas être écrite est omise et signalée.check_skipped
CHECK constraints added WITH NOCHECK or disablednon crééeSQL Server n'applique pas ces contraintes CHECK, donc les lignes peuvent les enfreindre.check_not_enforced
filtered and columnstore indexes, and indexes on CLOB columnsnon 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 UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULTsuppriméLes clés étrangères d'Oracle n'agissent qu'à la suppression, avec CASCADE ou SET NULL.foreign_key_action_unsupported
names over 128 bytesraccourciDepuis Oracle 12.2, les noms contiennent 128 octets ; ceux de SQL Server contiennent 128 caractères.name_shortened
foreign keys to tables the dump doesn't createnon crééeUne clé ne peut pas désigner une table absente.foreign_key_skipped
tables on a partition schemeune seule table avec les lignes de chaque partitionLes lignes sont les mêmes ; partitionnez à nouveau la table dans Oracle si besoin.partitions_dropped
temporal tables (SYSTEM_VERSIONING)deux tables : les lignes actuelles et l'historiqueLa table et sa table d'historique sont copiées comme tables simples ; Oracle ne garde pas l'historique de lui-même.system_versioning_dropped
schemasun 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 sont donc préfixées par le nom de leur schéma, et celles de dbo gardent leur nom.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, functions, procedures, triggers, synonyms, types and partition functionslistés dans le rapportLeur code est écrit en T-SQL ; ils sont donc listés pour que vous les recréiez.not_converted_objects
scripts without CREATE TABLE (data only)types déduits des valeursUn script de données seules ne contient que des lignes, donc les types viennent des valeurs.no_schema
expressions in INSERT valuesNULLUn convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.expression_value
types IntoSQL doesn't knowCLOBLe texte contient n'importe quelle valeur ; changez le type après le chargement.unknown_type
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 @sql_server.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 SQL Server pour un meilleur résultat

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

  • Dans SSMS, faites un clic droit sur la base de données, Tasks, Generate Scripts, et choisissez les tables. dbatools, mssql-scripter et les autres outils construits sur la même bibliothèque écrivent le même script.
  • Sous Advanced, réglez Types of data to script sur Schema and data. Un script du schéma seul contient des tables sans lignes.
  • Enregistrez-le en Unicode, le format par défaut de SSMS, ou en UTF-8 : les deux se lisent de la même façon, et gzip fonctionne aussi.

Ce qui n'est pas converti

Les vues, fonctions, procédures, déclencheurs, synonymes, règles et politiques de sécurité sont écrits en T-SQL. Ils sont listés par nom dans le rapport, jamais supprimés en silence, pour que vous puissiez les réécrire pour Oracle.

Questions sur SQL Server vers Oracle

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.

Lit-il le fichier UTF-16 qu'enregistre SSMS ?

Oui. SSMS enregistre les scripts en UTF-16 par défaut, et le convertisseur lit l'UTF-16 comme l'UTF-8, compressés en gzip ou non, avec GO entre les lots.

De quelles versions de SQL Server le script peut-il venir ?

Les scripts que SSMS, dbatools ou mssql-scripter écrivent depuis SQL Server 2017. Chaque script de test vient de SQL Server 2017, 2022 et 2025 et est comparé à sa source cellule par cellule.

Les valeurs IDENTITY sont-elles gardées ?

Oui. Les colonnes IDENTITY deviennent des colonnes d'identité, chaque ligne garde son identifiant, et le suivant reprend après le plus élevé. Les séquences sont créées avec les mêmes options.

Que deviennent money, datetimeoffset et les autres types SQL Server ?

bit devient NUMBER(1), datetime2 TIMESTAMP avec chaque chiffre, datetimeoffset TIMESTAMP WITH TIME ZONE avec son décalage, et nvarchar(max) CLOB si ses valeurs ne tiennent pas dans un VARCHAR2. Les chaînes vides deviennent NULL, car Oracle les stocke ainsi, et le rapport les compte.

Et les procédures, les déclencheurs et les vues ?

Ils sont listés par nom dans le rapport et ne sont pas convertis, car chaque base de données les écrit dans son propre langage.

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

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