Przejdź do treści
Strona główna IntoSQL

Konwertuj PostgreSQL do SQL Server

Upuść zwykły zrzut z pg_dump lub pg_dumpall jako .sql lub .sql.gz i pobierz skrypt SQL Server z tymi samymi tabelami, kluczami, indeksami i danymi. Każda wartość, której SQL Server nie może przechować bez zmian, i każdy obiekt, którego nie przenosi, są wymienione w raporcie.

Twój plik
sqlshop_2024_postgres.sqlPlik przykładowy, 6,2 kB
Twoja baza danych

18 wierszy przekonwertowanych, 2 poprawki, brak odrzuconych

Pokaż

Tabele w pliku shop_2024_postgres.sqlZrzut PostgreSQL 18.6 · zapisany przez pg_dump · utf8mb4

  • customers8 wierszy1
    8 kolumn
    idint not null
    namenvarchar(max) not null
    emailnvarchar(450) not null
    countrynvarchar(2) not null
    is_activebit not null
    tagsnvarchar(max) not null
    signed_update
    created_atdatetimeoffset(6) not null
  • orders10 wierszy1
    10 kolumn
    idint not null
    customer_idint not null
    statusnvarchar(9) not null
    totaldecimal(10,2) not null
    itemssmallint not null
    ordered_atdatetime2(6) not null
    shipped_atdatetime2(6)
    notenvarchar(max)
    detailsnvarchar(max)
    deliverynvarchar(100)

Nieprzekonwertowane

  • Widok paid_orders

Każda baza danych zapisuje je we własnym języku. Przepisz je dla 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

Poprawki

  1. "tags" w tabeli customers to text[], czego SQL Server nie ma, więc ma typ nvarchar(max) z tymi samymi wartościami.
  2. "delivery" w tabeli orders to interval, czego SQL Server nie ma, więc ma typ nvarchar(100) z tymi samymi wartościami.

Do sprawdzenia

  • Widoki, wyzwalacze, procedury i zdarzenia nie są konwertowane: 1 obiekt, każdy wymieniony w raporcie. Utwórz je ręcznie w SQL Server.
  • Wartości domyślnej "tags" w tabeli customers nie da się zapisać dla SQL Server (a value its type can't hold), więc kolumna nie ma wartości domyślnej. Dodaj wartość domyślną ręcznie, jeśli nowe wiersze jej potrzebują.
  • Indeks idx_orders_details w tabeli orders używa wyrażenia, którego nie da się zapisać dla SQL Server (an index on an expression), więc go nie utworzono. Utwórz indeks ręcznie, jeśli zapytania go potrzebują.
  • W "shipped_at" tabeli orders 1 data poza zakresem SQL Server, np. infinity, staje się NULL. SQL Server przechowuje lata od 1 do 9999 bez nieskończoności; jeśli te daty są ważne, zastąp je w źródle.

Plik jest konwertowany na tym komputerze i nigdy nie jest wysyłany.

Inne przykłady:

Co zmienia się między PostgreSQL a SQL Server

Każdy wiersz to reguła stosowana przez konwerter, z wpisem, który dodaje do raportu, gdy reguła coś zmienia w twoich danych.

  • boolean

    bit

    bit przechowuje true jako 1, a false jako 0.

  • varchar(n), char(n), text

    nvarchar(n); text jako nvarchar(max) albo nvarchar(450), gdy używa go klucz i każda wartość się mieści

    nvarchar mieści każdy znak. SQL Server nie indeksuje nvarchar(max), więc tekst w kluczu ma rozmiar, który mieści się w kluczu.

  • text comparison

    dokładne (Latin1_General_100_BIN2); citext bez rozróżniania wielkości liter (Latin1_General_100_CI_AS_SC)

    Zwykłe porównywanie w SQL Server ignoruje wielkość liter, a text w PostgreSQL nie, więc każda kolumna określa, jak porównuje, a klucze unikalne rozróżniają te same wiersze.

  • numeric(p,s) past 38 digits; numeric without a precision

    nvarchar; decimal(p,s) dopasowany do wartości, gdy mieszczą się w 38 cyfrach

    decimal w SQL Server mieści 38 cyfr. numeric bez precyzji dostaje najwęższy decimal, w którym mieszczą się jego wartości; szersze liczby są zapisywane jako tekst, aby każda cyfra pozostała dokładna.

    Wpis w raporcie: decimal_as_text

  • money

    decimal(19,2)

    money w SQL Server jest mniejszy niż w PostgreSQL i ma cztery miejsca po przecinku; decimal(19,2) mieści każdą kwotę, bez symbolu waluty dodanego przez ustawienia regionalne serwera.

    Wpis w raporcie: type_replaced

  • interval

    nvarchar(100) z tekstem PostgreSQL

    SQL Server nie ma typu interval; tekst zachowuje każdą część.

    Wpis w raporcie: type_replaced

  • arrays (integer[], text[]...)

    nvarchar(max) z tablicą JSON

    SQL Server nie ma tablic. Tablica JSON zachowuje każdy element i NULL, a OPENJSON ją odczytuje.

    Wpis w raporcie: type_replaced

  • ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types

    nvarchar(max) z tekstem PostgreSQL

    SQL Server nie ma odpowiedniego typu, więc każda wartość zachowuje tekst zapisany przez PostgreSQL.

    Wpis w raporcie: type_replaced

  • json, jsonb

    nvarchar(max)

    Funkcje JSON w SQL Server odczytują JSON z tekstu.

  • timestamp

    datetime2

    timestamp bez strefy czasowej to wskazanie zegara, jak datetime2.

  • timestamp with time zone

    datetimeoffset w UTC

    datetimeoffset zachowuje moment; każda wartość jest zapisywana w UTC, ten sam moment niezależnie od przesunięcia w zrzucie.

  • time with 24:00:00 in it

    nvarchar(17)

    time w SQL Server kończy się na 23:59:59.9999999, więc kolumna z 24:00:00 zachowuje swój tekst.

    Wpis w raporcie: time_as_interval

  • infinity, -infinity and BC dates

    NULL

    SQL Server przechowuje lata od 1 do 9999 bez nieskończoności. Te wartości stają się NULL, a raport je liczy.

    Wpis w raporcie: date_out_of_range

  • NaN and Infinity in numeric, real and double precision

    NULL

    Liczby w SQL Server nie mają NaN ani Infinity, więc te wartości stają się NULL, a raport je liczy.

    Wpis w raporcie: invalid_value_null

  • NOT NULL columns with values that become NULL

    NOT NULL usunięte

    Kolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało.

    Wpis w raporcie: not_null_relaxed

  • enum types

    nvarchar z CHECK jego etykiet

    Tekst z ograniczeniem CHECK zachowuje te same wartości.

  • enum columns holding values outside their labels

    nvarchar bez CHECK

    Wartości spoza etykiet nie przeszłyby ograniczenia CHECK, więc nie jest ono tworzone.

    Wpis w raporcie: enum_check_skipped

  • uuid, inet, cidr, macaddr

    uniqueidentifier; adresy jako nvarchar

    uniqueidentifier to UUID w SQL Server; adresy są zapisywane jako tekst.

  • bytea

    varbinary(max)

    Bajty pozostają bajtami.

  • bit(n), bit varying

    bit dla jednego bitu; bigint do 63 bitów; powyżej cyfry jako tekst

    Pojedynczy bit to tak lub nie; dłuższe ciągi bitów są zapisywane jako liczba, którą tworzą ich bity.

  • oid, xid, cid

    bigint z CHECK, że wartość nie jest ujemna

    bigint mieści każdą wartość.

  • serial, identity

    IDENTITY, kontynuowane po najwyższym id

    Skopiowane id ładują się z IDENTITY_INSERT, a licznik idzie dalej od najwyższego z nich lub od następnej wartości sekwencji, zależnie od tego, która jest wyższa.

  • a second serial or identity column in a table

    zwykła liczba całkowita

    SQL Server liczy jedną kolumnę IDENTITY na tabelę; każda inna zachowuje wartości bez licznika.

    Wpis w raporcie: counter_dropped

  • sequences not owned by a column

    CREATE SEQUENCE ... AS bigint, z następną wartością

    SQL Server ma sekwencje z tymi samymi opcjami; każda idzie dalej od miejsca, w którym zostawił ją zrzut.

  • generated columns

    kolumny obliczane, PERSISTED, gdy źródło je przechowuje

    SQL Server oblicza je na te same dwa sposoby.

  • generated columns with functions SQL Server lacks

    zwykła kolumna z wartościami

    Formuła, której nie da się zapisać dla SQL Server, zostawia zwykłą kolumnę z wartościami ze zrzutu i wpis w raporcie.

    Wpis w raporcie: generated_not_translated

  • defaults with functions SQL Server lacks, and defaults from a sequence

    brak wartości domyślnej

    Wartość domyślna, której nie da się zapisać dla SQL Server, jest pomijana i zgłaszana w raporcie.

    Wpis w raporcie: default_not_translated

  • CHECK constraints

    przetłumaczone, wewnątrz CREATE TABLE

    CHECK w definicji tabeli działa przy ładowaniu każdego wiersza.

  • CHECK constraints with functions SQL Server lacks

    nie jest tworzone

    Ograniczenie CHECK, którego nie da się zapisać dla SQL Server, jest pomijane i zgłaszane w raporcie.

    Wpis w raporcie: check_skipped

  • CHECK ... NOT VALID

    nie jest tworzone

    PostgreSQL nigdy nie sprawdził wierszy, które były wcześniej, więc mogą je łamać.

    Wpis w raporcie: check_not_valid

  • gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a key

    nie jest tworzone

    SQL Server indeksuje kolumny, a nie wyrażenia, i nie nvarchar(max).

    Wpis w raporcie: index_skipped

  • foreign keys

    po danych z WITH NOCHECK, potem sprawdzany z ostrzeżeniem o osieroconych wierszach

    Klucz jest tworzony po wierszach i sprawdzany na końcu; wiersze bez rodzica zostawiają go niesprawdzonym z ostrzeżeniem, zamiast zatrzymać ładowanie.

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

    NO ACTION

    SQL Server odrzuca kaskady, które mogłyby dwa razy dotrzeć do tej samej tabeli; PostgreSQL na nie pozwala.

    Wpis w raporcie: foreign_key_action_dropped

  • foreign keys to tables the dump doesn't create

    nie jest tworzone

    Klucz nie może wskazywać tabeli, której nie ma.

    Wpis w raporcie: foreign_key_skipped

  • partitioned tables

    jedna tabela z wierszami wszystkich partycji

    Wiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w SQL Server.

    Wpis w raporcie: partitions_dropped

  • views, functions, procedures, triggers, rules, policies, extensions and types

    wymienione w raporcie

    Ich kod jest napisany w języku PostgreSQL, więc trafiają na listę do ręcznego odtworzenia.

    Wpis w raporcie: not_converted_objects

  • dumps without CREATE TABLE (--data-only)

    typy odczytane z wartości

    Zrzut samych danych zawiera tylko wiersze, więc typy pochodzą z wartości.

    Wpis w raporcie: no_schema

  • expressions in INSERT values

    NULL

    Konwerter, który nie uruchamia bazy danych, nie może ich obliczyć.

    Wpis w raporcie: expression_value

  • types IntoSQL doesn't know

    nvarchar(max)

    Tekst mieści każdą wartość; zmień typ po załadowaniu.

    Wpis w raporcie: unknown_type

  • text that isn't valid in its encoding

    błędne bajty jako znak zastępczy

    nvarchar przechowuje tekst Unicode.

    Wpis w raporcie: invalid_utf8_replaced

  • text decoded twice (ñ)

    skopiowane bez zmian

    Zrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.

    Wpis w raporcie: mojibake_suspected

W PostgreSQLW SQL ServerWpis w raporcie
booleanbitbit przechowuje true jako 1, a false jako 0.
varchar(n), char(n), textnvarchar(n); text jako nvarchar(max) albo nvarchar(450), gdy używa go klucz i każda wartość się mieścinvarchar mieści każdy znak. SQL Server nie indeksuje nvarchar(max), więc tekst w kluczu ma rozmiar, który mieści się w kluczu.
text comparisondokładne (Latin1_General_100_BIN2); citext bez rozróżniania wielkości liter (Latin1_General_100_CI_AS_SC)Zwykłe porównywanie w SQL Server ignoruje wielkość liter, a text w PostgreSQL nie, więc każda kolumna określa, jak porównuje, a klucze unikalne rozróżniają te same wiersze.
numeric(p,s) past 38 digits; numeric without a precisionnvarchar; decimal(p,s) dopasowany do wartości, gdy mieszczą się w 38 cyfrachdecimal w SQL Server mieści 38 cyfr. numeric bez precyzji dostaje najwęższy decimal, w którym mieszczą się jego wartości; szersze liczby są zapisywane jako tekst, aby każda cyfra pozostała dokładna.decimal_as_text
moneydecimal(19,2)money w SQL Server jest mniejszy niż w PostgreSQL i ma cztery miejsca po przecinku; decimal(19,2) mieści każdą kwotę, bez symbolu waluty dodanego przez ustawienia regionalne serwera.type_replaced
intervalnvarchar(100) z tekstem PostgreSQLSQL Server nie ma typu interval; tekst zachowuje każdą część.type_replaced
arrays (integer[], text[]...)nvarchar(max) z tablicą JSONSQL Server nie ma tablic. Tablica JSON zachowuje każdy element i NULL, a OPENJSON ją odczytuje.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesnvarchar(max) z tekstem PostgreSQLSQL Server nie ma odpowiedniego typu, więc każda wartość zachowuje tekst zapisany przez PostgreSQL.type_replaced
json, jsonbnvarchar(max)Funkcje JSON w SQL Server odczytują JSON z tekstu.
timestampdatetime2timestamp bez strefy czasowej to wskazanie zegara, jak datetime2.
timestamp with time zonedatetimeoffset w UTCdatetimeoffset zachowuje moment; każda wartość jest zapisywana w UTC, ten sam moment niezależnie od przesunięcia w zrzucie.
time with 24:00:00 in itnvarchar(17)time w SQL Server kończy się na 23:59:59.9999999, więc kolumna z 24:00:00 zachowuje swój tekst.time_as_interval
infinity, -infinity and BC datesNULLSQL Server przechowuje lata od 1 do 9999 bez nieskończoności. Te wartości stają się NULL, a raport je liczy.date_out_of_range
NaN and Infinity in numeric, real and double precisionNULLLiczby w SQL Server nie mają NaN ani Infinity, więc te wartości stają się NULL, a raport je liczy.invalid_value_null
NOT NULL columns with values that become NULLNOT NULL usunięteKolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało.not_null_relaxed
enum typesnvarchar z CHECK jego etykietTekst z ograniczeniem CHECK zachowuje te same wartości.
enum columns holding values outside their labelsnvarchar bez CHECKWartości spoza etykiet nie przeszłyby ograniczenia CHECK, więc nie jest ono tworzone.enum_check_skipped
uuid, inet, cidr, macaddruniqueidentifier; adresy jako nvarcharuniqueidentifier to UUID w SQL Server; adresy są zapisywane jako tekst.
byteavarbinary(max)Bajty pozostają bajtami.
bit(n), bit varyingbit dla jednego bitu; bigint do 63 bitów; powyżej cyfry jako tekstPojedynczy bit to tak lub nie; dłuższe ciągi bitów są zapisywane jako liczba, którą tworzą ich bity.
oid, xid, cidbigint z CHECK, że wartość nie jest ujemnabigint mieści każdą wartość.
serial, identityIDENTITY, kontynuowane po najwyższym idSkopiowane id ładują się z IDENTITY_INSERT, a licznik idzie dalej od najwyższego z nich lub od następnej wartości sekwencji, zależnie od tego, która jest wyższa.
a second serial or identity column in a tablezwykła liczba całkowitaSQL Server liczy jedną kolumnę IDENTITY na tabelę; każda inna zachowuje wartości bez licznika.counter_dropped
sequences not owned by a columnCREATE SEQUENCE ... AS bigint, z następną wartościąSQL Server ma sekwencje z tymi samymi opcjami; każda idzie dalej od miejsca, w którym zostawił ją zrzut.
generated columnskolumny obliczane, PERSISTED, gdy źródło je przechowujeSQL Server oblicza je na te same dwa sposoby.
generated columns with functions SQL Server lackszwykła kolumna z wartościamiFormuła, której nie da się zapisać dla SQL Server, zostawia zwykłą kolumnę z wartościami ze zrzutu i wpis w raporcie.generated_not_translated
defaults with functions SQL Server lacks, and defaults from a sequencebrak wartości domyślnejWartość domyślna, której nie da się zapisać dla SQL Server, jest pomijana i zgłaszana w raporcie.default_not_translated
CHECK constraintsprzetłumaczone, wewnątrz CREATE TABLECHECK w definicji tabeli działa przy ładowaniu każdego wiersza.
CHECK constraints with functions SQL Server lacksnie jest tworzoneOgraniczenie CHECK, którego nie da się zapisać dla SQL Server, jest pomijane i zgłaszane w raporcie.check_skipped
CHECK ... NOT VALIDnie jest tworzonePostgreSQL nigdy nie sprawdził wierszy, które były wcześniej, więc mogą je łamać.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a keynie jest tworzoneSQL Server indeksuje kolumny, a nie wyrażenia, i nie nvarchar(max).index_skipped
foreign keyspo danych z WITH NOCHECK, potem sprawdzany z ostrzeżeniem o osieroconych wierszachKlucz jest tworzony po wierszach i sprawdzany na końcu; wiersze bez rodzica zostawiają go niesprawdzonym z ostrzeżeniem, zamiast zatrzymać ładowanie.
ON DELETE or ON UPDATE that cascades in a cycle or along a second pathNO ACTIONSQL Server odrzuca kaskady, które mogłyby dwa razy dotrzeć do tej samej tabeli; PostgreSQL na nie pozwala.foreign_key_action_dropped
foreign keys to tables the dump doesn't createnie jest tworzoneKlucz nie może wskazywać tabeli, której nie ma.foreign_key_skipped
partitioned tablesjedna tabela z wierszami wszystkich partycjiWiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w SQL Server.partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and typeswymienione w raporcieIch kod jest napisany w języku PostgreSQL, więc trafiają na listę do ręcznego odtworzenia.not_converted_objects
dumps without CREATE TABLE (--data-only)typy odczytane z wartościZrzut samych danych zawiera tylko wiersze, więc typy pochodzą z wartości.no_schema
expressions in INSERT valuesNULLKonwerter, który nie uruchamia bazy danych, nie może ich obliczyć.expression_value
types IntoSQL doesn't knownvarchar(max)Tekst mieści każdą wartość; zmień typ po załadowaniu.unknown_type
text that isn't valid in its encodingbłędne bajty jako znak zastępczynvarchar przechowuje tekst Unicode.invalid_utf8_replaced
text decoded twice (ñ)skopiowane bez zmianZrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.mojibake_suspected

Załaduj skrypt do SQL Server

Skrypt tworzy tabele, kopiuje wiersze, a potem dodaje klucze, indeksy i klucze obce, więc ładuje się szybko i zatrzymuje przy pierwszym błędzie.

sqlcmd -b -f 65001 -S localhost -d mydb -i postgresql.sql_server.sql

Klucze obce są dodawane z WITH NOCHECK, a potem sprawdzane. Jeśli wiersz wskazuje na nieistniejący wiersz, skrypt podaje, którego ograniczenia to dotyczy, i zostawia je niesprawdzone, zamiast przerwać w połowie.

Przy dużym zrzucie uruchom sqlcmd na tej samej maszynie co serwer. Każda partia do 1000 wierszy jest zatwierdzana osobno, więc dziennik transakcji pozostaje mały.

Jak zrobić zrzut PostgreSQL dla najlepszego wyniku

Konwerter odczytuje to, co zawiera zrzut. Te opcje zachowują w nim więcej twoich danych:

  • --format=plain, domyślny w pg_dump, zapisuje SQL. Archiwum custom lub directory (-Fc, -Fd) zamienisz na SQL poleceniem pg_restore -f dump.sql, bez serwera bazy danych.
  • --no-owner --no-privileges pomijają role i uprawnienia, które konwerter i tak pomija, więc zrzut jest mniejszy.
  • pg_dumpall zapisuje każdą bazę danych w jednym pliku; nazwy tabel każdej z nich zaczynają się od jej nazwy, więc nic się nie powtarza.

Co nie jest konwertowane

Widoki, widoki zmaterializowane, funkcje, procedury, wyzwalacze, reguły, polityki bezpieczeństwa wierszy, rozszerzenia i typy są pisane we własnym języku PostgreSQL. Raport wymienia je z nazwy i nigdy nie pomija ich po cichu, więc możesz je przepisać dla SQL Server.

Pytania o konwersję PostgreSQL do SQL Server

Nie ma tu odpowiedzi? Napisz do nas przez stronę kontaktu, a odpowie człowiek. Strona kontaktu

Czy mój zrzut jest wysyłany?

Nie. Konwerter działa w przeglądarce i odczytuje zrzut z dysku po kawałku, więc nigdy nie opuszcza on twojego komputera. Aplikacja na komputer i wiersz poleceń też konwertują na twoim komputerze.

Jak duży może być zrzut?

Konwerter nigdy nie trzyma całego zrzutu w pamięci: czyta plik dwa razy, fragmentami, i zapisuje skrypt na bieżąco. Zrzuty wielogigabajtowe konwertują się w przeglądarce, w aplikacji na komputer i w wierszu poleceń.

Czy odczytuje archiwa pg_dump -Fc?

Nie bezpośrednio: archiwum custom to format binarny. pg_restore -f dump.sql dump.backup zamienia je na zwykły SQL, który czyta konwerter, bez łączenia z serwerem. Konwerter informuje o tym, gdy dostanie archiwum.

Z jakich wersji PostgreSQL może pochodzić zrzut?

Zrzuty zapisane przez pg_dump i pg_dumpall z PostgreSQL od wersji 10, z wierszami COPY lub INSERT. Każdy testowy zrzut pochodzi z PostgreSQL 13 i 18 i jest porównywany ze źródłem komórka po komórce.

Czy wartości serial i identity są zachowywane?

Tak. Kolumna serial lub identity każdej tabeli staje się kolumną IDENTITY, każdy wiersz zachowuje swoje id, a kolejne id idzie po najwyższym. SQL Server liczy jedną kolumnę na tabelę, więc każda inna zachowuje wartości bez licznika.

Co dzieje się z tablicami, typami enum i innymi typami PostgreSQL?

Tablice stają się tablicami JSON, wartości logiczne bit, uuid uniqueidentifier, a znaczniki czasu ze strefą datetimeoffset. Tekst porównuje się dokładnie, jak w PostgreSQL, a citext bez rozróżniania wielkości liter. Zakresy, typy geometryczne i typy złożone zachowują tekst PostgreSQL.

A funkcje, wyzwalacze i widoki?

Raport wymienia je z nazwy, ale nie są konwertowane, bo każda baza danych zapisuje je we własnym języku.

Na jakich wersjach SQL Server ładuje się skrypt?

SQL Server od 2017 do 2025. Ten sam skrypt ładuje się na każdej z nich i zatrzymuje przy pierwszym błędzie, jeśli coś pójdzie nie tak.