Converti SQL Server in Oracle
Trascina lo script che Generate Scripts di SSMS scrive con schema e dati, come .sql o .sql.gz, UTF-16 o UTF-8, 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.
18 righe convertite, 2 correzioni, nessuna rifiutata
Tabelle in shop_2024_sqlserver.sqlDump SQL Server · scritto da SQL Server Management Objects · utf-8
ordersscritta come ORDERS10 righe1
11 colonne ID NUMBER(10) not null CUSTOMER_ID NUMBER(10) not null STATUS VARCHAR2(10 CHAR) not null TOTAL NUMBER(19,4) not null ITEMS NUMBER(3) 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) customersscritta come CUSTOMERS8 righe1
8 colonne ID NUMBER(10) not null NAME VARCHAR2(100 CHAR) not null EMAIL VARCHAR2(200 CHAR) not null COUNTRY VARCHAR2(2 CHAR) not null IS_ACTIVE NUMBER(1) not null SIGNED_UP DATE CREATED_AT TIMESTAMP(0) WITH TIME ZONE not null ROW_VERSION RAW(8)
Non convertiti
- Vista paid_orders
- Trigger orders_no_negative
Ogni database li scrive nel proprio linguaggio. Riscrivili per 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;
Correzioni
- "total_with_tax" di orders è salvata nella sorgente; Oracle la calcola in lettura.
- "row_version" di customers è una versione di riga che SQL Server imposta da solo; il dump non ha valori per essa, quindi è RAW(8) e vuota.
Da controllare
- 6 colonne di testo confrontano ignorando maiuscole e minuscole nell'origine; Oracle confronta in modo esatto, quindi chiavi univoche e ricerche possono comportarsi diversamente. Usa una collation o un tipo di colonna che ignora maiuscole e minuscole nelle colonne che ne hanno bisogno.
- 2 viste, trigger, routine o eventi non sono convertiti; il report li elenca uno per uno. Ricreali a mano in Oracle.
- Il vincolo CHECK check1 su orders non si può scrivere per Oracle (function isjson), quindi non viene creato. Se conta, scrivi a mano il vincolo CHECK.
- L'indice idx_orders_pending su orders usa un'espressione che non si può scrivere per Oracle (filtered index), quindi non viene creato. Crea l'indice a mano se le query ne hanno bisogno.
- Il valore predefinito di "order_ref" in orders non si può scrivere per Oracle (function uuid), quindi la colonna non ha un valore predefinito. Aggiungi a mano il valore predefinito se le nuove righe ne hanno bisogno.
Il tuo file viene convertito su questo computer e non viene mai caricato.
Altri esempi:
Cosa cambia da SQL Server 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.
bit
NUMBER(1) con un CHECK di 0 e 1
Oracle 21c non ha un tipo di colonna booleano; 1 e 0 mantengono i valori su ogni versione.
char(n), varchar(n), nchar(n), nvarchar(n)
VARCHAR2(n CHAR), contando i caratteri
Le lunghezze contano i caratteri, come il nvarchar di SQL Server.
varchar(max), nvarchar(max), text, ntext
VARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte, altrimenti CLOB
Un VARCHAR2 contiene 4000 byte di default e Oracle non può indicizzare un CLOB, quindi il testo resta VARCHAR2 quando i valori ci stanno ed è un CLOB quando no.
Riga del report: text_as_lob
empty strings and empty binary 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
decimal(p,s), money, smallmoney
NUMBER(p,s); money come NUMBER(19,4)
NUMBER contiene 38 cifre, come decimal, quindi ogni valore è esatto.
datetime, datetime2, smalldatetime
TIMESTAMP(p)
Un datetime è l'ora letta su un orologio, come il TIMESTAMP di Oracle, che mantiene fino a nove cifre di secondo. date diventa DATE, che contiene anche un'ora del giorno che resta a mezzanotte.
datetimeoffset
TIMESTAMP WITH TIME ZONE, con l'offset di ogni valore
Oracle mantiene gli offset da -12:00 a +14:00; un valore con un offset oltre -12:00 è scritto in UTC, lo stesso istante.
time
INTERVAL DAY TO SECOND dalla mezzanotte
Oracle non ha un tipo per l'ora del giorno; un intervallo dalla mezzanotte contiene ogni valore.
dates that aren't valid
NULL
Un valore che non è una data diventa NULL e il report lo conta.
Riga del report: date_out_of_range
json (SQL Server 2025)
CLOB
Gli stessi valori JSON, che le funzioni JSON di Oracle leggono.
uniqueidentifier
VARCHAR2(36)
Gli stessi identificatori, scritti in minuscolo.
binary, varbinary, image
RAW(n) e BLOB
I byte restano byte.
geometry, geography
BLOB con i byte propri di SQL Server
SSMS scrive i valori spaziali nella serializzazione di SQL Server, che viene mantenuta byte per byte.
Riga del report: spatial_as_native
rowversion, timestamp
BLOB, vuoto
SQL Server imposta da solo la versione di riga e SSMS non ne scrive i valori nello script.
Riga del report: rowversion_empty
xml, sql_variant, hierarchyid, vector
VARCHAR2 o CLOB con il testo di ogni valore
Oracle non ha un tipo equivalente; xml e sql_variant mantengono il testo di ogni valore e hierarchyid il suo percorso, come /1/2/.
Riga del report: type_replaced
collations that ignore case (_CI_)
confronto esatto
Oracle confronta il testo in modo esatto salvo indicazione diversa, quindi le colonne che in SQL Server ignoravano le maiuscole ora distinguono Ana da ana.
Riga del report: case_insensitive_collation
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.
CREATE SEQUENCE
CREATE SEQUENCE con le stesse opzioni
Le sequenze di Oracle funzionano allo stesso modo. SSMS non scrive fin dove è arrivata una sequenza, quindi riparte da dove è stata creata.
computed columns
colonne virtuali
Oracle calcola le colonne generate solo in lettura; le colonne PERSISTED diventano virtuali con gli stessi valori.
Riga del report: stored_as_virtual
computed columns with functions Oracle lacks
una colonna semplice
Una formula che non si può scrivere lascia una colonna semplice e una riga nel report; SSMS non scrive valori per le colonne calcolate.
Riga del report: generated_not_translated
defaults with functions Oracle lacks, and NEXT VALUE FOR
nessun valore predefinito
Un valore predefinito che non si può scrivere viene omesso e segnalato.
Riga del report: default_not_translated
CHECK constraints
tradotti
Gli stessi CHECK, verificati mentre ogni riga si carica.
CHECK constraints with functions Oracle lacks
non creato
Un vincolo CHECK che non si può scrivere viene omesso e segnalato.
Riga del report: check_skipped
CHECK constraints added WITH NOCHECK or disabled
non creato
SQL Server non applica questi CHECK, quindi le righe potrebbero violarli.
Riga del report: check_not_enforced
filtered and columnstore indexes, and indexes on CLOB columns
non creato
IntoSQL scrive indici b-tree su colonne intere; ricrea gli altri dopo il caricamento.
Riga del report: index_skipped
foreign keys
dopo i dati ENABLE NOVALIDATE, poi validata con un avviso sulle righe orfane
La chiave verifica subito le nuove righe e viene validata alla fine; righe senza padre la lasciano non validata con un avviso invece di fermare il caricamento.
ON 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
names over 128 bytes
accorciato
Da Oracle 12.2 i nomi contengono 128 byte; quelli di SQL Server 128 caratteri.
Riga del report: name_shortened
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
tables on a partition scheme
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
temporal tables (SYSTEM_VERSIONING)
due tabelle: le righe attuali e la cronologia
La tabella e la sua tabella di cronologia vengono copiate come tabelle semplici; Oracle non mantiene la cronologia da solo.
Riga del report: system_versioning_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 dbo mantengono il loro nome.
Riga del report: schemas_merged
NOT NULL columns with values that become NULL
NOT NULL rimosso
Una colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe.
Riga del report: not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functions
elencati nel report
Il loro codice è scritto in T-SQL, quindi vengono elencati perché tu li ricrei.
Riga del report: not_converted_objects
scripts without CREATE TABLE (data only)
tipi ricavati dai valori
Uno script 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
NUL characters in text
mantenuto
VARCHAR2 e CLOB possono contenere un carattere NUL, quindi il valore viene copiato così com'è.
text that isn't valid in its encoding
i byte errati come carattere di sostituzione
Lo script è UTF-8 e ogni valore deve essere testo valido.
Riga del report: invalid_utf8_replaced
text decoded twice (ñ)
copiato così com'è
Lo script contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala.
Riga del report: mojibake_suspected
| In SQL Server | In Oracle | Riga del report |
|---|---|---|
| bit | NUMBER(1) con un CHECK di 0 e 1Oracle 21c non ha un tipo di colonna booleano; 1 e 0 mantengono i valori su ogni versione. | |
| char(n), varchar(n), nchar(n), nvarchar(n) | VARCHAR2(n CHAR), contando i caratteriLe lunghezze contano i caratteri, come il nvarchar di SQL Server. | |
| varchar(max), nvarchar(max), text, ntext | VARCHAR2(4000 CHAR) quando ogni valore sta in 4000 byte, altrimenti CLOBUn VARCHAR2 contiene 4000 byte di default e Oracle non può indicizzare un CLOB, quindi il testo resta VARCHAR2 quando i valori ci stanno ed è un CLOB quando no. | text_as_lob |
| empty strings and empty binary values | NULLOracle salva una stringa vuota come NULL, quindi un valore che era ' si rilegge come NULL. Il report li conta per colonna. | empty_string_null |
| decimal(p,s), money, smallmoney | NUMBER(p,s); money come NUMBER(19,4)NUMBER contiene 38 cifre, come decimal, quindi ogni valore è esatto. | |
| datetime, datetime2, smalldatetime | TIMESTAMP(p)Un datetime è l'ora letta su un orologio, come il TIMESTAMP di Oracle, che mantiene fino a nove cifre di secondo. date diventa DATE, che contiene anche un'ora del giorno che resta a mezzanotte. | |
| datetimeoffset | TIMESTAMP WITH TIME ZONE, con l'offset di ogni valoreOracle mantiene gli offset da -12:00 a +14:00; un valore con un offset oltre -12:00 è scritto in UTC, lo stesso istante. | |
| time | INTERVAL DAY TO SECOND dalla mezzanotteOracle non ha un tipo per l'ora del giorno; un intervallo dalla mezzanotte contiene ogni valore. | |
| dates that aren't valid | NULLUn valore che non è una data diventa NULL e il report lo conta. | date_out_of_range |
| json (SQL Server 2025) | CLOBGli stessi valori JSON, che le funzioni JSON di Oracle leggono. | |
| uniqueidentifier | VARCHAR2(36)Gli stessi identificatori, scritti in minuscolo. | |
| binary, varbinary, image | RAW(n) e BLOBI byte restano byte. | |
| geometry, geography | BLOB con i byte propri di SQL ServerSSMS scrive i valori spaziali nella serializzazione di SQL Server, che viene mantenuta byte per byte. | spatial_as_native |
| rowversion, timestamp | BLOB, vuotoSQL Server imposta da solo la versione di riga e SSMS non ne scrive i valori nello script. | rowversion_empty |
| xml, sql_variant, hierarchyid, vector | VARCHAR2 o CLOB con il testo di ogni valoreOracle non ha un tipo equivalente; xml e sql_variant mantengono il testo di ogni valore e hierarchyid il suo percorso, come /1/2/. | type_replaced |
| collations that ignore case (_CI_) | confronto esattoOracle confronta il testo in modo esatto salvo indicazione diversa, quindi le colonne che in SQL Server ignoravano le maiuscole ora distinguono Ana da ana. | case_insensitive_collation |
| IDENTITY | GENERATED BY DEFAULT ON NULL AS IDENTITY, che riparte dopo l'id più altoGli id copiati si caricano così come sono, e il contatore riparte dopo il più alto. | |
| CREATE SEQUENCE | CREATE SEQUENCE con le stesse opzioniLe sequenze di Oracle funzionano allo stesso modo. SSMS non scrive fin dove è arrivata una sequenza, quindi riparte da dove è stata creata. | |
| computed columns | colonne virtualiOracle calcola le colonne generate solo in lettura; le colonne PERSISTED diventano virtuali con gli stessi valori. | stored_as_virtual |
| computed columns with functions Oracle lacks | una colonna sempliceUna formula che non si può scrivere lascia una colonna semplice e una riga nel report; SSMS non scrive valori per le colonne calcolate. | generated_not_translated |
| defaults with functions Oracle lacks, and NEXT VALUE FOR | nessun valore predefinitoUn valore predefinito che non si può scrivere viene omesso e segnalato. | default_not_translated |
| CHECK constraints | tradottiGli stessi CHECK, verificati mentre ogni riga si carica. | |
| CHECK constraints with functions Oracle lacks | non creatoUn vincolo CHECK che non si può scrivere viene omesso e segnalato. | check_skipped |
| CHECK constraints added WITH NOCHECK or disabled | non creatoSQL Server non applica questi CHECK, quindi le righe potrebbero violarli. | check_not_enforced |
| filtered and columnstore indexes, and indexes on CLOB columns | non creatoIntoSQL scrive indici b-tree su colonne intere; ricrea gli altri dopo il caricamento. | index_skipped |
| foreign keys | dopo i dati ENABLE NOVALIDATE, poi validata con un avviso sulle righe orfaneLa chiave verifica subito le nuove righe e viene validata alla fine; righe senza padre la lasciano non validata con un avviso invece di fermare il caricamento. | |
| ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT | rimossoLe chiavi esterne di Oracle agiscono solo in eliminazione, con CASCADE o SET NULL. | foreign_key_action_unsupported |
| names over 128 bytes | accorciatoDa Oracle 12.2 i nomi contengono 128 byte; quelli di SQL Server 128 caratteri. | name_shortened |
| foreign keys to tables the dump doesn't create | non creatoUna chiave non può riferirsi a una tabella che non c'è. | foreign_key_skipped |
| tables on a partition scheme | una tabella con le righe di ogni partizioneLe righe sono le stesse; partiziona di nuovo la tabella in Oracle se serve. | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | due tabelle: le righe attuali e la cronologiaLa tabella e la sua tabella di cronologia vengono copiate come tabelle semplici; Oracle non mantiene la cronologia da solo. | system_versioning_dropped |
| schemas | uno schema, tabelle con il nome del loro schema davantiLo script si carica nello schema dell'utente che lo esegue, quindi le tabelle di schemi diversi hanno davanti il nome del loro schema; le tabelle in dbo mantengono il loro nome. | schemas_merged |
| NOT NULL columns with values that become NULL | NOT NULL rimossoUna colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe. | not_null_relaxed |
| views, functions, procedures, triggers, synonyms, types and partition functions | elencati nel reportIl loro codice è scritto in T-SQL, quindi vengono elencati perché tu li ricrei. | not_converted_objects |
| scripts without CREATE TABLE (data only) | tipi ricavati dai valoriUno script di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori. | no_schema |
| expressions in INSERT values | NULLUn convertitore che non esegue un database non può valutarle. | expression_value |
| types IntoSQL doesn't know | CLOBIl testo contiene qualsiasi valore; cambia il tipo dopo il caricamento. | unknown_type |
| NUL characters in text | mantenutoVARCHAR2 e CLOB possono contenere un carattere NUL, quindi il valore viene copiato così com'è. | |
| text that isn't valid in its encoding | i byte errati come carattere di sostituzioneLo script è UTF-8 e ogni valore deve essere testo valido. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiato così com'èLo script contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala. | mojibake_suspected |
Carica lo script in Oracle
Lo script crea le tabelle, copia le righe, poi aggiunge chiavi, indici e chiavi esterne, così si carica in fretta e si ferma al primo errore.
NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @sql_server.oracle.sqlLe chiavi esterne vengono aggiunte ENABLE NOVALIDATE, così le nuove righe sono controllate subito, e poi validate. Se una riga vecchia punta a una riga che non esiste, lo script dice quale vincolo e lo lascia non validato, invece di fallire a metà.
Per un dump grande, esegui SQL*Plus sulla stessa macchina del database. Lo script fa il commit ogni 100 righe. L'utente che lo esegue ha bisogno di CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER e CREATE PROCEDURE, e di una quota sul suo tablespace.
Fai il dump di SQL Server per il miglior risultato
Il convertitore legge ciò che il dump contiene. Con queste opzioni il dump conserva più dei tuoi dati:
- In SSMS, clic destro sul database, Tasks, Generate Scripts, e scegli le tabelle. dbatools, mssql-scripter e altri strumenti basati sulla stessa libreria scrivono lo stesso script.
- In Advanced, imposta Types of data to script su Schema and data. Uno script del solo schema ha tabelle senza righe.
- Salvalo come Unicode, il default di SSMS, o come UTF-8: entrambi vengono letti allo stesso modo, e funziona anche gzip.
Cosa non viene convertito
Viste, funzioni, procedure, trigger, sinonimi, regole e policy di sicurezza sono scritti in T-SQL. Sono elencati per nome nel report, mai rimossi in silenzio, così puoi riscriverli per Oracle.
Domande sulla conversione da SQL Server 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 il file UTF-16 che salva SSMS?
Sì. SSMS salva gli script in UTF-16 di default, e il convertitore legge allo stesso modo UTF-16 e UTF-8, compressi con gzip o no, con GO tra i batch.
Da quali versioni di SQL Server può provenire lo script?
Script scritti da SSMS, dbatools o mssql-scripter da SQL Server 2017 in poi. Ogni script di test viene da SQL Server 2017, 2022 e 2025 ed è confrontato con la sorgente cella per cella.
I valori IDENTITY vengono mantenuti?
Sì. Le colonne IDENTITY diventano colonne identity, ogni riga mantiene il suo id e il prossimo id riparte dopo il più alto. Le sequenze vengono create con le stesse opzioni.
Cosa succede a money, datetimeoffset e altri tipi di SQL Server?
bit diventa NUMBER(1), datetime2 TIMESTAMP con ogni cifra, datetimeoffset TIMESTAMP WITH TIME ZONE con il suo offset, e nvarchar(max) CLOB quando i valori non stanno in un VARCHAR2. Le stringhe vuote diventano NULL, come le salva Oracle, e il report le conta.
E procedure, 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 script di test si carica su 21c e 23ai, fermandosi al primo errore se qualcosa va storto.