PostgreSQL omzetten naar SQL Server
Zet een gewone dump van pg_dump of pg_dumpall neer, als .sql of .sql.gz, en download een SQL Server-script met dezelfde tabellen, sleutels, indexen en data. Elke waarde die SQL Server niet ongewijzigd kan bevatten, en elk object dat het niet overneemt, staat in het rapport.
18 rijen geconverteerd, 2 correcties, geen afgewezen
Tabellen in shop_2024_postgres.sqlPostgreSQL 18.6-dump · geschreven door pg_dump · utf8mb4
customers8 rijen1
8 kolommen id int not null name nvarchar(max) not null email nvarchar(450) not null country nvarchar(2) not null is_active bit not null tags nvarchar(max) not null signed_up date created_at datetimeoffset(6) not null orders10 rijen1
10 kolommen id int not null customer_id int not null status nvarchar(9) not null total decimal(10,2) not null items smallint not null ordered_at datetime2(6) not null shipped_at datetime2(6) note nvarchar(max) details nvarchar(max) delivery nvarchar(100)
Niet geconverteerd
- Weergave paid_orders
Elke database schrijft deze in een eigen taal. Herschrijf ze voor SQL Server.
-- Written by IntoSQL from a PostgreSQL dump. Load it with: sqlcmd -b -f 65001 -d <database> -i <file>
SET NOCOUNT ON;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
GO
CREATE TABLE [dbo].[customers] (
[id] int IDENTITY(1001, 1) NOT NULL,
[name] nvarchar(max) COLLATE Latin1_General_100_BIN2 NOT NULL,
[email] nvarchar(450) COLLATE Latin1_General_100_BIN2 NOT NULL,
[country] nvarchar(2) COLLATE Latin1_General_100_BIN2 DEFAULT N'US' NOT NULL,
[is_active] bit DEFAULT 1 NOT NULL,
[tags] nvarchar(max) COLLATE Latin1_General_100_BIN2 NOT NULL,
[signed_up] date NULL,
[created_at] datetimeoffset(6) DEFAULT SYSDATETIMEOFFSET() NOT NULL,
CONSTRAINT [PK_customers] PRIMARY KEY ([id])
);
GO
CREATE TABLE [dbo].[orders] (
[id] int IDENTITY(5001, 1) NOT NULL,
[customer_id] int NOT NULL,
[status] nvarchar(9) COLLATE Latin1_General_100_BIN2 DEFAULT N'pending' NOT NULL,
[total] decimal(10,2) NOT NULL,
[items] smallint DEFAULT 1 NOT NULL,
[ordered_at] datetime2(6) NOT NULL,
[shipped_at] datetime2(6) NULL,
[note] nvarchar(max) COLLATE Latin1_General_100_BIN2 NULL,
[details] nvarchar(max) COLLATE Latin1_General_100_BIN2 NULL,
[delivery] nvarchar(100) COLLATE Latin1_General_100_BIN2 NULL,
CONSTRAINT [CK_orders_status] CHECK ([status] IN (N'pending', N'paid', N'shipped', N'cancelled')),
CONSTRAINT [orders_total_check] CHECK ([total] >= (0)),
CONSTRAINT [PK_orders] PRIMARY KEY ([id])
);
GO
SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [tags], [signed_up], [created_at]) VALUES
(1,N'Ana Martínez',N'ana@example.com',N'MX',1,N'["vip"]','2023-01-15','2023-01-15 10:24:00+00:00'),
(2,N'Zoë Müller',N'zoe@example.de',N'DE',1,N'[]','2023-02-03','2023-02-03 08:11:42+00:00'),
(3,N'José Peña',N'jose@example.es',N'ES',0,N'["wholesale","late payer"]','2023-03-21','2023-03-21 19:05:17+00:00'),
(4,N'李雷',N'lilei@example.cn',N'CN',1,N'[]','2023-05-09','2023-05-09 02:40:00+00:00'),
(5,N'Noah O''Brien',N'noah@example.ie',N'IE',1,N'[]',NULL,'2023-06-30 14:00:00+00:00'),
(6,N'Amélie Laurent',N'amelie@example.fr',N'FR',1,N'["vip"]','2024-01-02','2024-01-02 09:30:00+00:00'),
(7,N'Ravi Patel',N'ravi@example.in',N'IN',0,N'[]','2024-02-29','2024-02-29 23:59:59+00:00'),
(8,N'Sofia Rossi 🌻',N'sofia@example.it',N'IT',1,N'[]','2024-04-12','2024-04-12 12:12:12+00:00');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [status], [total], [items], [ordered_at], [shipped_at], [note], [details], [delivery]) VALUES
(1,1,N'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,N'{"gift": false}',N'1 day 06:30:00'),
(2,2,N'paid',54.00,1,'2024-03-02 11:15:00',NULL,N'Gift wrap 🎁',N'{"gift": true, "wrap": "red"}',NULL),
(3,1,N'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,N'Customer changed their mind',NULL,NULL),
(4,4,N'shipped',980.00,12,'2024-03-05 02:10:00','2024-03-07 08:00:00',N'请小心轻放',N'{"fragile": true}',N'2 days 05:50:00'),
(5,5,N'pending',45.75,2,'2024-03-08 17:20:00',NULL,N'Leave at the door; ring twice',NULL,NULL),
(6,6,N'shipped',310.40,5,'2024-03-10 13:00:00','2024-03-11 09:00:00',N'Fragile: "glass"',N'{"fragile": true}',N'20:00:00'),
(7,8,N'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,NULL,NULL),
(8,2,N'shipped',19.99,1,'2024-03-12 08:00:00',NULL,N'Shipped date set to infinity by an old import',NULL,NULL),
(9,3,N'shipped',64.00,2,'2024-03-14 15:30:00','2024-03-15 10:00:00',N'Two parcels',N'{"parcels": [1, 2]}',N'18:30:00'),
(10,7,N'paid',1499.00,1,'2024-03-15 21:05:00',NULL,N'C:\Users\ravi\invoice.pdf',NULL,NULL);
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO
-- Indexes, foreign keys, counters and triggers, after the rows.
CREATE UNIQUE INDEX [customers_email_key] ON [dbo].[customers] ([email]);
CREATE INDEX [idx_orders_customer] ON [dbo].[orders] ([customer_id]);
CREATE INDEX [idx_orders_status_date] ON [dbo].[orders] ([status], [ordered_at]);
ALTER TABLE [dbo].[orders] WITH NOCHECK ADD CONSTRAINT [orders_customer_id_fkey] FOREIGN KEY ([customer_id]) REFERENCES [dbo].[customers] ([id]);
BEGIN TRY ALTER TABLE [dbo].[orders] WITH CHECK CHECK CONSTRAINT [orders_customer_id_fkey]; END TRY BEGIN CATCH PRINT N'Foreign key ' + N'[orders_customer_id_fkey]' + N' has rows without a parent: it stays unchecked, and new rows are checked.'; END CATCH;
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[customers]); IF @next IS NOT NULL BEGIN IF @next < 1000 SET @next = 1000; DBCC CHECKIDENT (N'[dbo].[customers]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
EXEC sys.sp_addextendedproperty @name = N'MS_Description', @value = N'People who bought at least once', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'customers';
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[orders]); IF @next IS NOT NULL BEGIN IF @next < 5000 SET @next = 5000; DBCC CHECKIDENT (N'[dbo].[orders]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
GO
Correcties
- "tags" van customers is text[], wat SQL Server niet heeft, dus het is nvarchar(max) met dezelfde waarden.
- "delivery" van orders is interval, wat SQL Server niet heeft, dus het is nvarchar(100) met dezelfde waarden.
Na te kijken
- 1 weergave, trigger, routine of gebeurtenis is niet geconverteerd; het rapport noemt ze allemaal. Maak ze met de hand opnieuw aan in SQL Server.
- De standaardwaarde van "tags" in customers kan niet voor SQL Server worden geschreven (a value its type can't hold), dus de kolom heeft geen standaardwaarde. Voeg de standaardwaarde met de hand toe als nieuwe rijen die nodig hebben.
- De index idx_orders_details op orders gebruikt een expressie die niet voor SQL Server kan worden geschreven (an index on an expression), dus hij wordt niet aangemaakt. Maak de index met de hand aan als query's hem nodig hebben.
- 1 waarde in "shipped_at" van orders is een datum die SQL Server niet kan opslaan, zoals infinity, dus die is NULL. SQL Server slaat jaren 1 tot en met 9999 op, zonder oneindig; vervang die datums in de bron als ze ertoe doen.
Je bestand wordt op deze computer omgezet en nooit geüpload.
Andere voorbeelden:
Wat er verandert van PostgreSQL naar SQL Server
Elke rij is een regel die de converter toepast, met de rapportregel die hij schrijft als de regel iets in je data verandert.
boolean
bit
bit bewaart true als 1 en false als 0.
varchar(n), char(n), text
nvarchar(n); text als nvarchar(max), of nvarchar(450) als een sleutel het gebruikt en elke waarde past
nvarchar bevat elk teken. SQL Server kan nvarchar(max) niet indexeren, dus tekst in een sleutel krijgt een lengte die in een sleutel past.
text comparison
exact (Latin1_General_100_BIN2); citext zonder op hoofdletters te letten (Latin1_General_100_CI_AS_SC)
De gebruikelijke collation van SQL Server negeert hoofdletters en text in PostgreSQL niet, dus elke kolom geeft aan hoe hij vergelijkt en unieke sleutels houden dezelfde rijen uit elkaar.
numeric(p,s) past 38 digits; numeric without a precision
nvarchar; decimal(p,s) afgestemd op de waarden als die in 38 cijfers passen
decimal in SQL Server bevat 38 cijfers. Een numeric zonder precisie krijgt het smalste decimal waarin de waarden passen; bredere getallen blijven tekst, zodat elk cijfer exact blijft.
Rapportregel: decimal_as_text
money
decimal(19,2)
money in SQL Server is kleiner dan in PostgreSQL en heeft vier decimalen; decimal(19,2) bevat elk bedrag, zonder het valutasymbool dat de locale van de server toevoegde.
Rapportregel: type_replaced
interval
nvarchar(100) met de tekst van PostgreSQL
SQL Server heeft geen interval-type; de tekst behoudt elk deel.
Rapportregel: type_replaced
arrays (integer[], text[]...)
nvarchar(max) met een JSON-array
SQL Server heeft geen arrays. Een JSON-array behoudt elk element en NULL, en OPENJSON leest hem.
Rapportregel: type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types
nvarchar(max) met de tekst van PostgreSQL
SQL Server heeft geen gelijkwaardig type, dus elke waarde behoudt de tekst die PostgreSQL schreef.
Rapportregel: type_replaced
json, jsonb
nvarchar(max)
De JSON-functies van SQL Server lezen JSON uit tekst.
timestamp
datetime2
Een timestamp zonder tijdzone is een kloktijd, net als datetime2.
timestamp with time zone
datetimeoffset in UTC
datetimeoffset bewaart het moment; elke waarde wordt in UTC geschreven: hetzelfde moment, welke offset de dump ook schreef.
time with 24:00:00 in it
nvarchar(17)
time in SQL Server eindigt bij 23:59:59.9999999, dus een kolom met 24:00:00 behoudt zijn tekst.
Rapportregel: time_as_interval
infinity, -infinity and BC dates
NULL
SQL Server slaat jaren 1 tot en met 9999 op, zonder oneindig. Die waarden worden NULL en het rapport telt ze.
Rapportregel: date_out_of_range
NaN and Infinity in numeric, real and double precision
NULL
Getallen in SQL Server kennen geen NaN of Infinity, dus die waarden worden NULL en het rapport telt ze.
Rapportregel: invalid_value_null
NOT NULL columns with values that become NULL
NOT NULL weggelaten
Een kolom waarvan waarden NULL moesten worden, kan NOT NULL niet houden, anders zou het laden stoppen.
Rapportregel: not_null_relaxed
enum types
nvarchar met een CHECK op de labels
Tekst met een check houdt dezelfde waarden.
enum columns holding values outside their labels
nvarchar zonder check
Waarden die niet bij de labels horen, zouden de check laten mislukken, dus de check wordt niet aangemaakt.
Rapportregel: enum_check_skipped
uuid, inet, cidr, macaddr
uniqueidentifier; adressen als nvarchar
uniqueidentifier is de UUID van SQL Server; adressen blijven tekst.
bytea
varbinary(max)
Bytes blijven bytes.
bit(n), bit varying
bit voor één bit; bigint tot 63 bits; daarboven tekstcijfers
Eén bit is een ja of nee; langere bitstrings worden opgeslagen als het getal dat hun bits vormen.
oid, xid, cid
bigint met een CHECK dat het niet negatief is
bigint bevat elke waarde.
serial, identity
IDENTITY, verdergaand na het hoogste id
De gekopieerde id's laden met IDENTITY_INSERT, en de teller gaat verder na het hoogste of na de volgende waarde van de sequence, welke hoger is.
a second serial or identity column in a table
een geheel getal zonder teller
SQL Server telt één IDENTITY-kolom per tabel; elke andere behoudt zijn waarden zonder teller.
Rapportregel: counter_dropped
sequences not owned by a column
CREATE SEQUENCE ... AS bigint, met de volgende waarde
SQL Server heeft sequences met dezelfde opties; elke sequence gaat verder waar de dump hem achterliet.
generated columns
berekende kolommen, PERSISTED als de bron ze opslaat
SQL Server berekent ze op dezelfde twee manieren.
generated columns with functions SQL Server lacks
een gewone kolom met de waarden
Een formule die niet voor SQL Server kan worden geschreven, levert een gewone kolom met de waarden uit de dump en een regel in het rapport op.
Rapportregel: generated_not_translated
defaults with functions SQL Server lacks, and defaults from a sequence
geen standaardwaarde
Een standaardwaarde die niet voor SQL Server kan worden geschreven, wordt weggelaten en gemeld.
Rapportregel: default_not_translated
CHECK constraints
vertaald, inline in CREATE TABLE
Inline checks worden getest terwijl elke rij laadt.
CHECK constraints with functions SQL Server lacks
niet aangemaakt
Een check die niet voor SQL Server kan worden geschreven, wordt weggelaten en gemeld.
Rapportregel: check_skipped
CHECK ... NOT VALID
niet aangemaakt
PostgreSQL heeft de rijen die er al waren nooit gecontroleerd, dus ze kunnen hem schenden.
Rapportregel: check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a key
niet aangemaakt
SQL Server indexeert kolommen, geen expressies, en geen nvarchar(max).
Rapportregel: index_skipped
foreign keys
na de data WITH NOCHECK, daarna gecontroleerd met een waarschuwing bij wezen
De sleutel wordt na de rijen aangemaakt en als laatste gecontroleerd; rijen zonder ouder laten hem ongecontroleerd met een waarschuwing, in plaats van het laden te stoppen.
ON DELETE or ON UPDATE that cascades in a cycle or along a second path
NO ACTION
SQL Server weigert cascades die een tabel twee keer kunnen bereiken; PostgreSQL staat ze toe.
Rapportregel: foreign_key_action_dropped
foreign keys to tables the dump doesn't create
niet aangemaakt
Een sleutel kan niet verwijzen naar een tabel die er niet is.
Rapportregel: foreign_key_skipped
partitioned tables
één tabel met de rijen van elke partitie
De rijen zijn dezelfde; partitioneer de tabel opnieuw in SQL Server als dat nodig is.
Rapportregel: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types
vermeld in het rapport
Hun code is geschreven in de taal van PostgreSQL, dus ze worden vermeld zodat je ze opnieuw kunt maken.
Rapportregel: not_converted_objects
dumps without CREATE TABLE (--data-only)
typen afgeleid uit de waarden
Een dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden.
Rapportregel: no_schema
expressions in INSERT values
NULL
Een converter die geen database draait, kan ze niet evalueren.
Rapportregel: expression_value
types IntoSQL doesn't know
nvarchar(max)
Tekst kan elke waarde bevatten; wijzig het type na het laden.
Rapportregel: unknown_type
text that isn't valid in its encoding
de foute bytes als het vervangingsteken
nvarchar bevat Unicode-tekst.
Rapportregel: invalid_utf8_replaced
text decoded twice (ñ)
ongewijzigd gekopieerd
De dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan.
Rapportregel: mojibake_suspected
| In PostgreSQL | In SQL Server | Rapportregel |
|---|---|---|
| boolean | bitbit bewaart true als 1 en false als 0. | |
| varchar(n), char(n), text | nvarchar(n); text als nvarchar(max), of nvarchar(450) als een sleutel het gebruikt en elke waarde pastnvarchar bevat elk teken. SQL Server kan nvarchar(max) niet indexeren, dus tekst in een sleutel krijgt een lengte die in een sleutel past. | |
| text comparison | exact (Latin1_General_100_BIN2); citext zonder op hoofdletters te letten (Latin1_General_100_CI_AS_SC)De gebruikelijke collation van SQL Server negeert hoofdletters en text in PostgreSQL niet, dus elke kolom geeft aan hoe hij vergelijkt en unieke sleutels houden dezelfde rijen uit elkaar. | |
| numeric(p,s) past 38 digits; numeric without a precision | nvarchar; decimal(p,s) afgestemd op de waarden als die in 38 cijfers passendecimal in SQL Server bevat 38 cijfers. Een numeric zonder precisie krijgt het smalste decimal waarin de waarden passen; bredere getallen blijven tekst, zodat elk cijfer exact blijft. | decimal_as_text |
| money | decimal(19,2)money in SQL Server is kleiner dan in PostgreSQL en heeft vier decimalen; decimal(19,2) bevat elk bedrag, zonder het valutasymbool dat de locale van de server toevoegde. | type_replaced |
| interval | nvarchar(100) met de tekst van PostgreSQLSQL Server heeft geen interval-type; de tekst behoudt elk deel. | type_replaced |
| arrays (integer[], text[]...) | nvarchar(max) met een JSON-arraySQL Server heeft geen arrays. Een JSON-array behoudt elk element en NULL, en OPENJSON leest hem. | type_replaced |
| ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types | nvarchar(max) met de tekst van PostgreSQLSQL Server heeft geen gelijkwaardig type, dus elke waarde behoudt de tekst die PostgreSQL schreef. | type_replaced |
| json, jsonb | nvarchar(max)De JSON-functies van SQL Server lezen JSON uit tekst. | |
| timestamp | datetime2Een timestamp zonder tijdzone is een kloktijd, net als datetime2. | |
| timestamp with time zone | datetimeoffset in UTCdatetimeoffset bewaart het moment; elke waarde wordt in UTC geschreven: hetzelfde moment, welke offset de dump ook schreef. | |
| time with 24:00:00 in it | nvarchar(17)time in SQL Server eindigt bij 23:59:59.9999999, dus een kolom met 24:00:00 behoudt zijn tekst. | time_as_interval |
| infinity, -infinity and BC dates | NULLSQL Server slaat jaren 1 tot en met 9999 op, zonder oneindig. Die waarden worden NULL en het rapport telt ze. | date_out_of_range |
| NaN and Infinity in numeric, real and double precision | NULLGetallen in SQL Server kennen geen NaN of Infinity, dus die waarden worden NULL en het rapport telt ze. | invalid_value_null |
| NOT NULL columns with values that become NULL | NOT NULL weggelatenEen kolom waarvan waarden NULL moesten worden, kan NOT NULL niet houden, anders zou het laden stoppen. | not_null_relaxed |
| enum types | nvarchar met een CHECK op de labelsTekst met een check houdt dezelfde waarden. | |
| enum columns holding values outside their labels | nvarchar zonder checkWaarden die niet bij de labels horen, zouden de check laten mislukken, dus de check wordt niet aangemaakt. | enum_check_skipped |
| uuid, inet, cidr, macaddr | uniqueidentifier; adressen als nvarcharuniqueidentifier is de UUID van SQL Server; adressen blijven tekst. | |
| bytea | varbinary(max)Bytes blijven bytes. | |
| bit(n), bit varying | bit voor één bit; bigint tot 63 bits; daarboven tekstcijfersEén bit is een ja of nee; langere bitstrings worden opgeslagen als het getal dat hun bits vormen. | |
| oid, xid, cid | bigint met een CHECK dat het niet negatief isbigint bevat elke waarde. | |
| serial, identity | IDENTITY, verdergaand na het hoogste idDe gekopieerde id's laden met IDENTITY_INSERT, en de teller gaat verder na het hoogste of na de volgende waarde van de sequence, welke hoger is. | |
| a second serial or identity column in a table | een geheel getal zonder tellerSQL Server telt één IDENTITY-kolom per tabel; elke andere behoudt zijn waarden zonder teller. | counter_dropped |
| sequences not owned by a column | CREATE SEQUENCE ... AS bigint, met de volgende waardeSQL Server heeft sequences met dezelfde opties; elke sequence gaat verder waar de dump hem achterliet. | |
| generated columns | berekende kolommen, PERSISTED als de bron ze opslaatSQL Server berekent ze op dezelfde twee manieren. | |
| generated columns with functions SQL Server lacks | een gewone kolom met de waardenEen formule die niet voor SQL Server kan worden geschreven, levert een gewone kolom met de waarden uit de dump en een regel in het rapport op. | generated_not_translated |
| defaults with functions SQL Server lacks, and defaults from a sequence | geen standaardwaardeEen standaardwaarde die niet voor SQL Server kan worden geschreven, wordt weggelaten en gemeld. | default_not_translated |
| CHECK constraints | vertaald, inline in CREATE TABLEInline checks worden getest terwijl elke rij laadt. | |
| CHECK constraints with functions SQL Server lacks | niet aangemaaktEen check die niet voor SQL Server kan worden geschreven, wordt weggelaten en gemeld. | check_skipped |
| CHECK ... NOT VALID | niet aangemaaktPostgreSQL heeft de rijen die er al waren nooit gecontroleerd, dus ze kunnen hem schenden. | check_not_valid |
| gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a key | niet aangemaaktSQL Server indexeert kolommen, geen expressies, en geen nvarchar(max). | index_skipped |
| foreign keys | na de data WITH NOCHECK, daarna gecontroleerd met een waarschuwing bij wezenDe sleutel wordt na de rijen aangemaakt en als laatste gecontroleerd; rijen zonder ouder laten hem ongecontroleerd met een waarschuwing, in plaats van het laden te stoppen. | |
| ON DELETE or ON UPDATE that cascades in a cycle or along a second path | NO ACTIONSQL Server weigert cascades die een tabel twee keer kunnen bereiken; PostgreSQL staat ze toe. | foreign_key_action_dropped |
| foreign keys to tables the dump doesn't create | niet aangemaaktEen sleutel kan niet verwijzen naar een tabel die er niet is. | foreign_key_skipped |
| partitioned tables | één tabel met de rijen van elke partitieDe rijen zijn dezelfde; partitioneer de tabel opnieuw in SQL Server als dat nodig is. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types | vermeld in het rapportHun code is geschreven in de taal van PostgreSQL, dus ze worden vermeld zodat je ze opnieuw kunt maken. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | typen afgeleid uit de waardenEen dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden. | no_schema |
| expressions in INSERT values | NULLEen converter die geen database draait, kan ze niet evalueren. | expression_value |
| types IntoSQL doesn't know | nvarchar(max)Tekst kan elke waarde bevatten; wijzig het type na het laden. | unknown_type |
| text that isn't valid in its encoding | de foute bytes als het vervangingstekennvarchar bevat Unicode-tekst. | invalid_utf8_replaced |
| text decoded twice (ñ) | ongewijzigd gekopieerdDe dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan. | mojibake_suspected |
Het script in SQL Server laden
Het script maakt de tabellen aan, kopieert de rijen en voegt daarna sleutels, indexen en refererende sleutels toe, zodat het snel laadt en bij de eerste fout stopt.
sqlcmd -b -f 65001 -S localhost -d mydb -i postgresql.sql_server.sqlRefererende sleutels worden toegevoegd met WITH NOCHECK en daarna gecontroleerd. Verwijst een rij naar een rij die niet bestaat, dan vertelt het script welke constraint het is en laat het die ongecontroleerd, in plaats van halverwege te mislukken.
Voer bij een grote dump sqlcmd uit op dezelfde machine als de server. Elke batch van maximaal 1000 rijen wordt apart gecommit, zodat het transactielogboek klein blijft.
Een dump van PostgreSQL maken voor het beste resultaat
De converter leest wat de dump bevat. Met deze opties blijft er meer van je data in staan:
- --format=plain, de standaard van pg_dump, schrijft SQL. Een custom- of directoryarchief (-Fc, -Fd) wordt SQL met pg_restore -f dump.sql, zonder databaseserver.
- --no-owner --no-privileges laten rollen en rechten weg, die de converter toch overslaat, dus de dump wordt kleiner.
- pg_dumpall zet elke database in één bestand; de tabellen van elke database krijgen de naam ervan, dus niets botst.
Wat niet wordt geconverteerd
Weergaven, gematerialiseerde weergaven, functies, procedures, triggers, regels, beveiligingsbeleid voor rijen, extensies en typen zijn geschreven in de eigen taal van PostgreSQL. Ze staan op naam in het rapport en worden nooit stilletjes weggelaten, zodat je ze kunt herschrijven voor SQL Server.
Vragen over PostgreSQL naar SQL Server
Staat je vraag er niet bij? Schrijf ons via de contactpagina en een mens antwoordt. Contactpagina
Wordt mijn dump geüpload?
Nee. De converter draait in je browser en leest de dump in delen van je schijf, dus hij verlaat je computer nooit. De desktopapp en de opdrachtregel converteren ook op je computer.
Hoe groot mag de dump zijn?
De converter houdt nooit de hele dump in het geheugen: hij leest het bestand twee keer, in bereiken, en schrijft het script gaandeweg. Dumps van meerdere gigabytes worden geconverteerd in de browser, in de desktopapp en met de opdrachtregel.
Leest het pg_dump -Fc-archieven?
Niet direct: een custom-archief is een binair formaat. pg_restore -f dump.sql dump.backup zet het om naar de gewone SQL die de converter leest, zonder verbinding met een server. De converter meldt dat als hij een archief krijgt.
Van welke PostgreSQL-versies kan de dump komen?
Dumps geschreven door pg_dump en pg_dumpall vanaf PostgreSQL 10, met rijen als COPY of INSERT. Elke testdump komt van PostgreSQL 13 en 18 en wordt cel voor cel met zijn bron vergeleken.
Blijven serial- en identity-waarden behouden?
Ja. De serial- of identity-kolom van elke tabel wordt een IDENTITY-kolom, elke rij behoudt zijn id, en het volgende id gaat verder na het hoogste. SQL Server telt één kolom per tabel, dus elke andere behoudt zijn waarden zonder teller.
Wat gebeurt er met arrays, enums en andere PostgreSQL-typen?
Arrays worden JSON-arrays, booleans bit, uuid uniqueidentifier en timestamps met tijdzone datetimeoffset. Tekst wordt exact vergeleken, zoals in PostgreSQL, en citext zonder op hoofdletters te letten. Ranges, geometrische typen en samengestelde typen behouden de tekst van PostgreSQL.
En functies, triggers en weergaven?
Ze staan op naam in het rapport en worden niet geconverteerd, omdat elke database ze in een eigen taal schrijft.
Op welke SQL Server-versies laadt het script?
SQL Server 2017 tot en met 2025. Hetzelfde script laadt op elk ervan en stopt bij de eerste fout als er iets misgaat.