Vai al contenuto
Home di IntoSQL

Converti SQL Server in PostgreSQL

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 PostgreSQL con le stesse tabelle, chiavi, indici e dati. Ogni valore che PostgreSQL non può contenere così com'è, e ogni oggetto che non supporta, è elencato nel report.

Il tuo file
sqlshop_2024_sqlserver.sqlFile di esempio, 11 kB
Il tuo database

18 righe convertite, 3 correzioni, nessuna rifiutata

Mostra

Tabelle in shop_2024_sqlserver.sqlDump SQL Server · scritto da SQL Server Management Objects · utf-8

  • orders10 righe2
    11 colonne
    idinteger not null
    customer_idinteger not null
    statusvarchar(10) not null
    totalnumeric(19,4) not null
    itemssmallint not null
    ordered_attimestamp(0) not null
    shipped_attimestamp(6)
    notetext
    detailstext
    order_refuuid not null
    total_with_taxnumeric(12,2)
  • customers8 righe1
    8 colonne
    idinteger not null
    namevarchar(100) not null
    emailvarchar(200) not null
    countryvarchar(2) not null
    is_activeboolean not null
    signed_update
    created_attimestamptz(0) not null
    row_versionbytea

Non convertiti

  • Vista paid_orders
  • Trigger orders_no_negative

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

-- Written by IntoSQL from a SQL Server dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';

CREATE TABLE orders (
    id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    customer_id integer NOT NULL,
    status varchar(10) DEFAULT 'pending' NOT NULL,
    total numeric(19,4) NOT NULL,
    items smallint DEFAULT 1 NOT NULL,
    ordered_at timestamp(0) NOT NULL,
    shipped_at timestamp(6),
    note text,
    details text,
    order_ref uuid DEFAULT (gen_random_uuid()::text) NOT NULL,
    total_with_tax numeric(12,2) GENERATED ALWAYS AS ((cast(total * (1.16) AS numeric(12,2)))::numeric(12,2)) STORED,
    CONSTRAINT orders_items_check CHECK (items >= 0),
    CONSTRAINT orders_check2 CHECK (status = 'cancelled' OR status = 'shipped' OR status = 'paid' OR status = 'pending'),
    CONSTRAINT orders_check3 CHECK (total >= (0))
);

CREATE TABLE customers (
    id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    name varchar(100) NOT NULL,
    email varchar(200) NOT NULL,
    country varchar(2) DEFAULT 'US' NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    signed_up date,
    created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    row_version bytea
);

COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1	Ana Martínez	ana@example.com	MX	t	2023-01-15	2023-01-15 10:24:00.000000+00:00
2	Zoë Müller	zoe@example.de	DE	t	2023-02-03	2023-02-03 08:11:42.000000+00:00
3	José Peña	jose@example.es	ES	f	2023-03-21	2023-03-21 19:05:17.000000+00:00
4	李雷	lilei@example.cn	CN	t	2023-05-09	2023-05-09 02:40:00.000000+00:00
5	Noah O'Brien	noah@example.ie	IE	t	\N	2023-06-30 14:00:00.000000+00:00
6	Amélie Laurent	amelie@example.fr	FR	t	2024-01-02	2024-01-02 09:30:00.000000+00:00
7	Ravi Patel	ravi@example.in	IN	f	2024-02-29	2024-02-29 23:59:59.000000+00:00
8	Sofia Rossi 🌻	sofia@example.it	IT	t	2024-04-12	2024-04-12 12:12:12.000000+00:00
\.

COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) FROM stdin;
1	1	shipped	129.9000	3	2024-03-01T10:00:00.000000	2024-03-02T16:30:00.123456	\N	{"gift": false}	0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f
2	2	paid	54.0000	1	2024-03-02T11:15:00.000000	\N	Gift wrap 🎁	{"gift": true, "wrap": "red"}	1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70
3	1	cancelled	12.5000	1	2024-03-03T09:45:00.000000	\N	Customer changed their mind	\N	2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081
4	4	shipped	980.0000	12	2024-03-05T02:10:00.000000	2024-03-07T08:00:00.000000	请小心轻放	{"fragile": true}	3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192
5	5	pending	45.7500	2	2024-03-08T17:20:00.000000	\N	Leave at the door; ring twice	\N	4f1e806c-7d5b-4c2e-9a99-5e6f708192a3
6	6	shipped	310.4000	5	2024-03-10T13:00:00.000000	2024-03-11T09:00:00.000000	Fragile: "glass"	{"fragile": true}	50f2917d-8e6c-4d3f-8baa-6f708192a3b4
7	8	paid	76.2000	2	2024-03-11T18:45:00.000000	\N	\N	\N	6103a28e-9f7d-4e40-9cbb-708192a3b4c5
8	2	shipped	19.9900	1	2024-03-12T08:00:00.000000	9999-12-31T23:59:59.999999	Shipped date set to the maximum by an old import	\N	7214b39f-a08e-4f51-8dcc-8192a3b4c5d6
9	3	shipped	64.0000	2	2024-03-14T15:30:00.000000	2024-03-15T10:00:00.000000	Two parcels	{"parcels": [1, 2]}	8325c4a0-b19f-4062-9edd-92a3b4c5d6e7
10	7	paid	1499.0000	1	2024-03-15T21:05:00.000000	\N	C:\\Users\\ravi\\invoice.pdf	\N	9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8
\.


-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_orders_customer ON orders (customer_id);
CREATE INDEX orders_idx_orders_status_date ON orders (status, ordered_at);
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_email ON customers (email);
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_email UNIQUE USING INDEX customers_email;
ALTER TABLE orders ADD CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
    ALTER TABLE orders VALIDATE CONSTRAINT orders_fkey;
EXCEPTION WHEN foreign_key_violation THEN
    RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'orders_fkey';
END $f$;
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 1), 2147483647)::bigint, false);
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1), 2147483647)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';

Correzioni

  1. "items" di orders è senza segno, quindi è diventata smallint con un vincolo CHECK che non sia negativa.
  2. "shipped_at" di orders è datetime2(7), con più cifre di secondo di quante ne mantenga PostgreSQL, quindi è timestamp(6) e le ultime cifre vengono troncate.
  3. "row_version" di customers è una versione di riga che SQL Server imposta da solo; il dump non ha valori per essa, quindi è bytea e vuota.

Da controllare

  • 6 colonne di testo confrontano ignorando maiuscole e minuscole nell'origine; PostgreSQL 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 PostgreSQL.
  • Il vincolo CHECK check1 su orders non si può scrivere per PostgreSQL (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 PostgreSQL (filtered index), quindi non viene creato. Crea l'indice a mano se le query ne hanno bisogno.

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

Altri esempi:

Cosa cambia da SQL Server a PostgreSQL

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

  • bit

    boolean

    bit contiene 1 e 0, che sono true e false di PostgreSQL.

  • tinyint

    smallint con un CHECK che non sia negativo

    Il tinyint di SQL Server va da 0 a 255; l'intero più piccolo di PostgreSQL ha segno, quindi un vincolo CHECK ne mantiene l'intervallo.

    Riga del report: unsigned_widened

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

    varchar(n) e text

    Il text di PostgreSQL contiene ogni carattere, quindi varchar e nvarchar sono lo stesso tipo.

  • decimal(p,s), money, smallmoney

    numeric(p,s); money come numeric(19,4)

    Ogni cifra viene mantenuta, money con i suoi quattro decimali.

  • datetime, datetime2, smalldatetime

    timestamp(p)

    Un datetime è l'ora letta su un orologio, come un timestamp senza fuso orario.

  • datetime2(7), time(7) and datetimeoffset(7)

    sei cifre di secondo, la settima troncata

    PostgreSQL mantiene i microsecondi; la settima cifra (100 nanosecondi) viene troncata, mai arrotondata, quindi nessun valore passa al secondo o al giorno successivo.

    Riga del report: fraction_cut

  • datetimeoffset

    timestamptz, gli stessi istanti

    timestamptz mantiene l'istante; PostgreSQL lo mostra nel fuso orario della sessione invece che con l'offset di ogni valore.

  • time

    time(p)

    Le stesse ore del giorno.

  • json (SQL Server 2025)

    jsonb

    Gli stessi valori JSON.

  • uniqueidentifier

    uuid

    Gli stessi identificatori, scritti in minuscolo.

  • binary, varbinary, image

    bytea

    I byte restano byte.

  • geometry, geography

    bytea 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

    bytea, vuota

    SQL Server imposta da solo una versione di riga e lo script di SSMS non ne include i valori.

    Riga del report: rowversion_empty

  • sql_variant, hierarchyid, vector

    text

    PostgreSQL non ha un tipo equivalente; sql_variant mantiene il testo di ogni valore e hierarchyid il suo percorso, come /1/2/. xml resta xml.

    Riga del report: type_replaced

  • collations that ignore case (_CI_)

    confronto esatto

    PostgreSQL confronta il testo in modo esatto, 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 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 PostgreSQL funzionano allo stesso modo. Lo script di SSMS non indica fin dove è arrivata una sequenza, quindi riparte da dove è stata creata.

  • computed columns

    colonne generate, STORED

    PostgreSQL dalla 13 alla 17 salva solo colonne generate STORED; la formula è la stessa, con CONCAT scritto in modo che NULL valga come vuoto come in SQL Server.

    Riga del report: virtual_as_stored

  • computed columns with functions PostgreSQL lacks

    una colonna semplice

    Una formula che non si può scrivere per PostgreSQL lascia una colonna semplice e una riga nel report; lo script di SSMS non include valori per le colonne calcolate.

    Riga del report: generated_not_translated

  • defaults with functions PostgreSQL lacks, and NEXT VALUE FOR

    nessun valore predefinito

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

    Riga del report: default_not_translated

  • CHECK constraints

    tradotti

    Gli stessi vincoli CHECK, verificati mentre si carica ogni riga.

  • CHECK constraints with functions PostgreSQL lacks

    non creato

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

    Riga del report: check_skipped

  • CHECK constraints added WITH NOCHECK or disabled

    non creato

    SQL Server non applica questi vincoli CHECK, quindi le righe potrebbero violarli.

    Riga del report: check_not_enforced

  • filtered and columnstore indexes

    non creato

    IntoSQL scrive indici b-tree su colonne; ricrea gli altri dopo il caricamento.

    Riga del report: index_skipped

  • foreign keys

    chiavi esterne, dopo le righe

    Le righe si caricano in qualsiasi ordine, e le chiavi le verificano dopo.

  • 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 PostgreSQL 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; PostgreSQL non mantiene la cronologia da solo.

    Riga del report: system_versioning_dropped

  • 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

    text

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

    Riga del report: unknown_type

  • 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

  • NUL characters in text

    rimosso

    Il testo di PostgreSQL non può contenere il carattere NUL. Viene rimosso e il report conta i valori.

    Riga del report: nul_removed

  • text that isn't valid in its encoding

    i byte errati come carattere di sostituzione

    Il testo di PostgreSQL deve essere UTF-8 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 ServerIn PostgreSQLRiga del report
bitbooleanbit contiene 1 e 0, che sono true e false di PostgreSQL.
tinyintsmallint con un CHECK che non sia negativoIl tinyint di SQL Server va da 0 a 255; l'intero più piccolo di PostgreSQL ha segno, quindi un vincolo CHECK ne mantiene l'intervallo.unsigned_widened
char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), textvarchar(n) e textIl text di PostgreSQL contiene ogni carattere, quindi varchar e nvarchar sono lo stesso tipo.
decimal(p,s), money, smallmoneynumeric(p,s); money come numeric(19,4)Ogni cifra viene mantenuta, money con i suoi quattro decimali.
datetime, datetime2, smalldatetimetimestamp(p)Un datetime è l'ora letta su un orologio, come un timestamp senza fuso orario.
datetime2(7), time(7) and datetimeoffset(7)sei cifre di secondo, la settima troncataPostgreSQL mantiene i microsecondi; la settima cifra (100 nanosecondi) viene troncata, mai arrotondata, quindi nessun valore passa al secondo o al giorno successivo.fraction_cut
datetimeoffsettimestamptz, gli stessi istantitimestamptz mantiene l'istante; PostgreSQL lo mostra nel fuso orario della sessione invece che con l'offset di ogni valore.
timetime(p)Le stesse ore del giorno.
json (SQL Server 2025)jsonbGli stessi valori JSON.
uniqueidentifieruuidGli stessi identificatori, scritti in minuscolo.
binary, varbinary, imagebyteaI byte restano byte.
geometry, geographybytea 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, timestampbytea, vuotaSQL Server imposta da solo una versione di riga e lo script di SSMS non ne include i valori.rowversion_empty
sql_variant, hierarchyid, vectortextPostgreSQL non ha un tipo equivalente; sql_variant mantiene il testo di ogni valore e hierarchyid il suo percorso, come /1/2/. xml resta xml.type_replaced
collations that ignore case (_CI_)confronto esattoPostgreSQL confronta il testo in modo esatto, quindi le colonne che in SQL Server ignoravano le maiuscole ora distinguono Ana da ana.case_insensitive_collation
IDENTITYGENERATED BY DEFAULT 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 SEQUENCECREATE SEQUENCE con le stesse opzioniLe sequenze di PostgreSQL funzionano allo stesso modo. Lo script di SSMS non indica fin dove è arrivata una sequenza, quindi riparte da dove è stata creata.
computed columnscolonne generate, STOREDPostgreSQL dalla 13 alla 17 salva solo colonne generate STORED; la formula è la stessa, con CONCAT scritto in modo che NULL valga come vuoto come in SQL Server.virtual_as_stored
computed columns with functions PostgreSQL lacksuna colonna sempliceUna formula che non si può scrivere per PostgreSQL lascia una colonna semplice e una riga nel report; lo script di SSMS non include valori per le colonne calcolate.generated_not_translated
defaults with functions PostgreSQL lacks, and NEXT VALUE FORnessun valore predefinitoUn valore predefinito che non si può scrivere per PostgreSQL viene omesso e segnalato.default_not_translated
CHECK constraintstradottiGli stessi vincoli CHECK, verificati mentre si carica ogni riga.
CHECK constraints with functions PostgreSQL lacksnon creatoUn vincolo CHECK che non si può scrivere per PostgreSQL viene omesso e segnalato.check_skipped
CHECK constraints added WITH NOCHECK or disablednon creatoSQL Server non applica questi vincoli CHECK, quindi le righe potrebbero violarli.check_not_enforced
filtered and columnstore indexesnon creatoIntoSQL scrive indici b-tree su colonne; ricrea gli altri dopo il caricamento.index_skipped
foreign keyschiavi esterne, dopo le righeLe righe si caricano in qualsiasi ordine, e le chiavi le verificano dopo.
foreign keys to tables the dump doesn't createnon creatoUna chiave non può riferirsi a una tabella che non c'è.foreign_key_skipped
tables on a partition schemeuna tabella con le righe di ogni partizioneLe righe sono le stesse; partiziona di nuovo la tabella in PostgreSQL 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; PostgreSQL non mantiene la cronologia da solo.system_versioning_dropped
NOT NULL columns with values that become NULLNOT NULL rimossoUna colonna i cui valori sono dovuti diventare NULL non può mantenere NOT NULL, altrimenti il caricamento si fermerebbe.not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functionselencati 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 valuesNULLUn convertitore che non esegue un database non può valutarle.expression_value
types IntoSQL doesn't knowtextIl testo contiene qualsiasi valore; cambia il tipo dopo il caricamento.unknown_type
dates that aren't validNULLUn valore che non è una data diventa NULL e il report lo conta.date_out_of_range
NUL characters in textrimossoIl testo di PostgreSQL non può contenere il carattere NUL. Viene rimosso e il report conta i valori.nul_removed
text that isn't valid in its encodingi byte errati come carattere di sostituzioneIl testo di PostgreSQL deve essere UTF-8 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 PostgreSQL

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.

psql -v ON_ERROR_STOP=1 -d mydb -f sql_server.postgresql.sql

Le chiavi esterne vengono aggiunte come NOT VALID e poi validate. Se una riga punta a una riga che non esiste, lo script ti dice quale vincolo, invece di fallire a metà.

Per un dump grande, crea prima il database ed esegui lo script con psql dalla stessa macchina del server.

IntoSQL Pro carica il file direttamente in PostgreSQL dall'app desktop o dalla riga di comando, senza scrivere uno script.

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

Domande sulla conversione da SQL Server a PostgreSQL

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 boolean, money numeric(19,4), uniqueidentifier uuid, xml xml e datetimeoffset timestamptz. datetime2 mantiene sei cifre di secondo, la settima viene tagliata. Le colonne che ignoravano le maiuscole confrontano in modo esatto, e il report dice quali.

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 PostgreSQL si carica lo script?

PostgreSQL dalla 13 alla 18. Lo stesso script si carica su ognuna, fermandosi al primo errore se qualcosa va storto.