Перейти к содержимому
Главная страница IntoSQL

Конвертация PostgreSQL в SQL Server

Перетащите обычный дамп из pg_dump или pg_dumpall в формате .sql или .sql.gz и скачайте скрипт SQL Server с теми же таблицами, ключами, индексами и данными. Каждое значение, которое SQL Server не может хранить как есть, и каждый объект, который он не переносит, указаны в отчете.

Ваш файл
sqlshop_2024_postgres.sqlПример файла, 6,2 кБ
Ваша база данных

18 строк конвертировано, 2 исправления, ни одна не отклонена

Показать

Таблицы в shop_2024_postgres.sqlДамп PostgreSQL 18.6 · создан программой pg_dump · utf8mb4

  • customers8 строк1
    8 столбцов
    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 строк1
    10 столбцов
    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)

Не конвертировано

  • Представление paid_orders

Каждая база данных пишет их на своем языке. Перепишите их для 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

Исправления

  1. "tags" таблицы customers имеет тип text[], которого нет в SQL Server, поэтому тип nvarchar(max) с теми же значениями.
  2. "delivery" таблицы orders имеет тип interval, которого нет в SQL Server, поэтому тип nvarchar(100) с теми же значениями.

Требует проверки

  • Не конвертированы представления, триггеры, процедуры и события (1 объект); отчет перечисляет каждый. Создайте их заново вручную в SQL Server.
  • Значение по умолчанию столбца "tags" таблицы customers нельзя записать для SQL Server (a value its type can't hold), поэтому у столбца его нет. Добавьте значение по умолчанию вручную, если оно нужно новым строкам.
  • Индекс idx_orders_details таблицы orders использует выражение, которое нельзя записать для SQL Server (an index on an expression), поэтому он не создан. Создайте индекс вручную, если он нужен запросам.
  • В "shipped_at" таблицы orders есть даты, которые SQL Server не может хранить (1 значение), например infinity; они заменены на NULL. SQL Server хранит годы с 1 по 9999 без бесконечности; если эти даты важны, замените их в источнике.

Файл конвертируется на этом компьютере и никуда не загружается.

Другие примеры:

Что меняется при переходе с PostgreSQL на SQL Server

Каждая строка - это правило, которое применяет конвертер, и строка отчета, которую он пишет, когда правило что-то меняет в ваших данных.

  • boolean

    bit

    bit хранит true как 1, а false как 0.

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

    nvarchar(n); text как nvarchar(max) или nvarchar(450), если он входит в ключ и все значения помещаются

    nvarchar вмещает любой символ. SQL Server не может индексировать nvarchar(max), поэтому размер text в ключе подбирается под ключ.

  • text comparison

    точное (Latin1_General_100_BIN2); citext без учета регистра (Latin1_General_100_CI_AS_SC)

    Обычная сортировка SQL Server не учитывает регистр, а text в PostgreSQL учитывает, поэтому для каждого столбца указано, как он сравнивает, и уникальные ключи различают те же строки.

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

    nvarchar; decimal(p,s) по значениям, если они укладываются в 38 цифр

    decimal в SQL Server вмещает 38 цифр. numeric без точности получает самый узкий decimal, в который помещаются его значения; более широкие числа хранятся как текст, чтобы каждая цифра осталась точной.

    Строка отчета: decimal_as_text

  • money

    decimal(19,2)

    money в SQL Server меньше, чем в PostgreSQL, и имеет четыре знака после запятой; decimal(19,2) вмещает любую сумму, без символа валюты, добавленного локалью сервера.

    Строка отчета: type_replaced

  • interval

    nvarchar(100) с текстом PostgreSQL

    В SQL Server нет типа interval; текст сохраняет каждую часть.

    Строка отчета: type_replaced

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

    nvarchar(max) с массивом JSON

    В SQL Server нет массивов. Массив JSON сохраняет каждый элемент и NULL, а OPENJSON его читает.

    Строка отчета: type_replaced

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

    nvarchar(max) с текстом PostgreSQL

    В SQL Server нет равнозначного типа, поэтому каждое значение сохраняет текст, записанный PostgreSQL.

    Строка отчета: type_replaced

  • json, jsonb

    nvarchar(max)

    Функции JSON в SQL Server читают JSON из текста.

  • timestamp

    datetime2

    timestamp without time zone - это показание часов, как datetime2.

  • timestamp with time zone

    datetimeoffset в UTC

    datetimeoffset сохраняет момент; каждое значение записывается в UTC: тот же момент, какое бы смещение ни записал дамп.

  • time with 24:00:00 in it

    nvarchar(17)

    time в SQL Server заканчивается на 23:59:59.9999999, поэтому столбец со значением 24:00:00 сохраняет свой текст.

    Строка отчета: time_as_interval

  • infinity, -infinity and BC dates

    NULL

    SQL Server хранит годы с 1 по 9999 без бесконечности. Такие значения становятся NULL, а отчет их подсчитывает.

    Строка отчета: date_out_of_range

  • NaN and Infinity in numeric, real and double precision

    NULL

    В числах SQL Server нет NaN и Infinity, поэтому такие значения становятся NULL, а отчет их подсчитывает.

    Строка отчета: invalid_value_null

  • NOT NULL columns with values that become NULL

    NOT NULL снимается

    Столбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится.

    Строка отчета: not_null_relaxed

  • enum types

    nvarchar с CHECK его меток

    Текст с проверкой хранит те же значения.

  • enum columns holding values outside their labels

    nvarchar без проверки

    Значения, которых нет среди меток, не прошли бы проверку, поэтому она не создается.

    Строка отчета: enum_check_skipped

  • uuid, inet, cidr, macaddr

    uniqueidentifier; адреса как nvarchar

    uniqueidentifier - это UUID в SQL Server; адреса хранятся как текст.

  • bytea

    varbinary(max)

    Байты остаются байтами.

  • bit(n), bit varying

    bit для одного бита; bigint до 63 бит; дальше цифры в тексте

    Один бит - это да или нет; более длинные битовые строки хранятся как число, которое составляют их биты.

  • oid, xid, cid

    bigint с CHECK на неотрицательность

    bigint вмещает любое значение.

  • serial, identity

    IDENTITY, продолжается после наибольшего id

    Скопированные id загружаются с IDENTITY_INSERT, а счетчик продолжается после наибольшего из них или со следующего значения последовательности, смотря что больше.

  • a second serial or identity column in a table

    обычное целое

    SQL Server нумерует один столбец IDENTITY на таблицу; любой другой сохраняет свои значения без счетчика.

    Строка отчета: counter_dropped

  • sequences not owned by a column

    CREATE SEQUENCE ... AS bigint со следующим значением

    В SQL Server есть последовательности с теми же параметрами; каждая продолжается с того места, где ее оставил дамп.

  • generated columns

    вычисляемые столбцы, PERSISTED, если источник их хранит

    SQL Server вычисляет их теми же двумя способами.

  • generated columns with functions SQL Server lacks

    обычный столбец со значениями

    Формула, которую нельзя записать для SQL Server, оставляет обычный столбец со значениями из дампа и строку в отчете.

    Строка отчета: generated_not_translated

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

    без значения по умолчанию

    Значение по умолчанию, которое нельзя записать для SQL Server, опускается и попадает в отчет.

    Строка отчета: default_not_translated

  • CHECK constraints

    переводится, внутри CREATE TABLE

    Встроенные проверки выполняются при загрузке каждой строки.

  • CHECK constraints with functions SQL Server lacks

    не создается

    Проверка, которую нельзя записать для SQL Server, опускается и попадает в отчет.

    Строка отчета: check_skipped

  • CHECK ... NOT VALID

    не создается

    PostgreSQL не проверял строки, которые были до нее, поэтому они могут ее нарушать.

    Строка отчета: check_not_valid

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

    не создается

    SQL Server индексирует столбцы, но не выражения и не nvarchar(max).

    Строка отчета: index_skipped

  • foreign keys

    после данных WITH NOCHECK, затем проверка с предупреждением о строках без родителя

    Ключ создается после строк и проверяется последним; при строках без родителя он остается непроверенным с предупреждением, и загрузка не останавливается.

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

    NO ACTION

    SQL Server отклоняет каскады, которые могут дойти до таблицы дважды; PostgreSQL их допускает.

    Строка отчета: foreign_key_action_dropped

  • foreign keys to tables the dump doesn't create

    не создается

    Ключ не может ссылаться на таблицу, которой нет.

    Строка отчета: foreign_key_skipped

  • partitioned tables

    одна таблица со строками всех секций

    Строки те же; при необходимости секционируйте таблицу заново в SQL Server.

    Строка отчета: partitions_dropped

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

    перечисляются в отчете

    Их код написан на языке PostgreSQL, поэтому они перечислены, чтобы вы создали их заново.

    Строка отчета: not_converted_objects

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

    типы определяются по значениям

    Дамп только с данными содержит лишь строки, поэтому типы берутся из значений.

    Строка отчета: no_schema

  • expressions in INSERT values

    NULL

    Конвертер, который не запускает базу данных, не может их вычислить.

    Строка отчета: expression_value

  • types IntoSQL doesn't know

    nvarchar(max)

    Тип text вмещает любое значение; измените тип после загрузки.

    Строка отчета: unknown_type

  • text that isn't valid in its encoding

    неверные байты заменяются символом замены

    nvarchar хранит текст Unicode.

    Строка отчета: invalid_utf8_replaced

  • text decoded twice (ñ)

    копируется как есть

    Дамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.

    Строка отчета: mojibake_suspected

В PostgreSQLВ SQL ServerСтрока отчета
booleanbitbit хранит true как 1, а false как 0.
varchar(n), char(n), textnvarchar(n); text как nvarchar(max) или nvarchar(450), если он входит в ключ и все значения помещаютсяnvarchar вмещает любой символ. SQL Server не может индексировать nvarchar(max), поэтому размер text в ключе подбирается под ключ.
text comparisonточное (Latin1_General_100_BIN2); citext без учета регистра (Latin1_General_100_CI_AS_SC)Обычная сортировка SQL Server не учитывает регистр, а text в PostgreSQL учитывает, поэтому для каждого столбца указано, как он сравнивает, и уникальные ключи различают те же строки.
numeric(p,s) past 38 digits; numeric without a precisionnvarchar; decimal(p,s) по значениям, если они укладываются в 38 цифрdecimal в SQL Server вмещает 38 цифр. numeric без точности получает самый узкий decimal, в который помещаются его значения; более широкие числа хранятся как текст, чтобы каждая цифра осталась точной.decimal_as_text
moneydecimal(19,2)money в SQL Server меньше, чем в PostgreSQL, и имеет четыре знака после запятой; decimal(19,2) вмещает любую сумму, без символа валюты, добавленного локалью сервера.type_replaced
intervalnvarchar(100) с текстом PostgreSQLВ SQL Server нет типа interval; текст сохраняет каждую часть.type_replaced
arrays (integer[], text[]...)nvarchar(max) с массивом JSONВ SQL Server нет массивов. Массив JSON сохраняет каждый элемент и NULL, а OPENJSON его читает.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesnvarchar(max) с текстом PostgreSQLВ SQL Server нет равнозначного типа, поэтому каждое значение сохраняет текст, записанный PostgreSQL.type_replaced
json, jsonbnvarchar(max)Функции JSON в SQL Server читают JSON из текста.
timestampdatetime2timestamp without time zone - это показание часов, как datetime2.
timestamp with time zonedatetimeoffset в UTCdatetimeoffset сохраняет момент; каждое значение записывается в UTC: тот же момент, какое бы смещение ни записал дамп.
time with 24:00:00 in itnvarchar(17)time в SQL Server заканчивается на 23:59:59.9999999, поэтому столбец со значением 24:00:00 сохраняет свой текст.time_as_interval
infinity, -infinity and BC datesNULLSQL Server хранит годы с 1 по 9999 без бесконечности. Такие значения становятся NULL, а отчет их подсчитывает.date_out_of_range
NaN and Infinity in numeric, real and double precisionNULLВ числах SQL Server нет NaN и Infinity, поэтому такие значения становятся NULL, а отчет их подсчитывает.invalid_value_null
NOT NULL columns with values that become NULLNOT NULL снимаетсяСтолбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится.not_null_relaxed
enum typesnvarchar с CHECK его метокТекст с проверкой хранит те же значения.
enum columns holding values outside their labelsnvarchar без проверкиЗначения, которых нет среди меток, не прошли бы проверку, поэтому она не создается.enum_check_skipped
uuid, inet, cidr, macaddruniqueidentifier; адреса как nvarcharuniqueidentifier - это UUID в SQL Server; адреса хранятся как текст.
byteavarbinary(max)Байты остаются байтами.
bit(n), bit varyingbit для одного бита; bigint до 63 бит; дальше цифры в текстеОдин бит - это да или нет; более длинные битовые строки хранятся как число, которое составляют их биты.
oid, xid, cidbigint с CHECK на неотрицательностьbigint вмещает любое значение.
serial, identityIDENTITY, продолжается после наибольшего idСкопированные id загружаются с IDENTITY_INSERT, а счетчик продолжается после наибольшего из них или со следующего значения последовательности, смотря что больше.
a second serial or identity column in a tableобычное целоеSQL Server нумерует один столбец IDENTITY на таблицу; любой другой сохраняет свои значения без счетчика.counter_dropped
sequences not owned by a columnCREATE SEQUENCE ... AS bigint со следующим значениемВ SQL Server есть последовательности с теми же параметрами; каждая продолжается с того места, где ее оставил дамп.
generated columnsвычисляемые столбцы, PERSISTED, если источник их хранитSQL Server вычисляет их теми же двумя способами.
generated columns with functions SQL Server lacksобычный столбец со значениямиФормула, которую нельзя записать для SQL Server, оставляет обычный столбец со значениями из дампа и строку в отчете.generated_not_translated
defaults with functions SQL Server lacks, and defaults from a sequenceбез значения по умолчаниюЗначение по умолчанию, которое нельзя записать для SQL Server, опускается и попадает в отчет.default_not_translated
CHECK constraintsпереводится, внутри CREATE TABLEВстроенные проверки выполняются при загрузке каждой строки.
CHECK constraints with functions SQL Server lacksне создаетсяПроверка, которую нельзя записать для SQL Server, опускается и попадает в отчет.check_skipped
CHECK ... NOT VALIDне создаетсяPostgreSQL не проверял строки, которые были до нее, поэтому они могут ее нарушать.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a keyне создаетсяSQL Server индексирует столбцы, но не выражения и не nvarchar(max).index_skipped
foreign keysпосле данных WITH NOCHECK, затем проверка с предупреждением о строках без родителяКлюч создается после строк и проверяется последним; при строках без родителя он остается непроверенным с предупреждением, и загрузка не останавливается.
ON DELETE or ON UPDATE that cascades in a cycle or along a second pathNO ACTIONSQL Server отклоняет каскады, которые могут дойти до таблицы дважды; PostgreSQL их допускает.foreign_key_action_dropped
foreign keys to tables the dump doesn't createне создаетсяКлюч не может ссылаться на таблицу, которой нет.foreign_key_skipped
partitioned tablesодна таблица со строками всех секцийСтроки те же; при необходимости секционируйте таблицу заново в SQL Server.partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and typesперечисляются в отчетеИх код написан на языке PostgreSQL, поэтому они перечислены, чтобы вы создали их заново.not_converted_objects
dumps without CREATE TABLE (--data-only)типы определяются по значениямДамп только с данными содержит лишь строки, поэтому типы берутся из значений.no_schema
expressions in INSERT valuesNULLКонвертер, который не запускает базу данных, не может их вычислить.expression_value
types IntoSQL doesn't knownvarchar(max)Тип text вмещает любое значение; измените тип после загрузки.unknown_type
text that isn't valid in its encodingневерные байты заменяются символом заменыnvarchar хранит текст Unicode.invalid_utf8_replaced
text decoded twice (ñ)копируется как естьДамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.mojibake_suspected

Загрузите скрипт в SQL Server

Скрипт создает таблицы, копирует строки, затем добавляет ключи, индексы и внешние ключи, поэтому загрузка идет быстро и останавливается на первой ошибке.

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

Внешние ключи добавляются WITH NOCHECK, а затем проверяются. Если строка ссылается на несуществующую строку, скрипт сообщает, какое это ограничение, и оставляет его непроверенным, а не прерывается на полпути.

Для большого дампа запускайте sqlcmd на той же машине, где работает сервер. Каждый пакет до 1000 строк фиксируется отдельно, поэтому журнал транзакций остается небольшим.

Как создать дамп PostgreSQL для лучшего результата

Конвертер читает то, что есть в дампе. Эти параметры сохраняют в нем больше ваших данных:

  • --format=plain, формат pg_dump по умолчанию, пишет SQL. Архив custom или directory (-Fc, -Fd) превращается в SQL командой pg_restore -f dump.sql, без сервера баз данных.
  • --no-owner --no-privileges исключают роли и права, которые конвертер все равно пропускает, поэтому дамп получается меньше.
  • pg_dumpall сохраняет все базы данных в один файл; имена таблиц каждой базы начинаются с ее имени, поэтому ничего не конфликтует.

Что не конвертируется

Представления, материализованные представления, функции, процедуры, триггеры, правила, политики защиты строк, расширения и типы написаны на собственном языке PostgreSQL. Они перечислены в отчете по имени и никогда не удаляются молча, чтобы вы могли переписать их для SQL Server.

Вопросы о PostgreSQL в SQL Server

Нет ответа на ваш вопрос? Напишите нам через страницу контактов, и вам ответит человек. Страница контактов

Мой дамп загружается на сервер?

Нет. Конвертер работает в вашем браузере и читает дамп с диска по частям, поэтому он никогда не покидает ваш компьютер. Приложение для компьютера и командная строка тоже конвертируют на вашем компьютере.

Насколько большим может быть дамп?

Конвертер никогда не держит весь дамп в памяти: он читает файл дважды, по диапазонам, и пишет скрипт по ходу чтения. Дампы в несколько гигабайт конвертируются в браузере, в приложении для компьютера и в командной строке.

Читает ли он архивы pg_dump -Fc?

Не напрямую: архив custom - это двоичный формат. pg_restore -f dump.sql dump.backup превращает его в обычный SQL, который читает конвертер, без подключения к серверу. Получив архив, конвертер так и сообщает.

Из каких версий PostgreSQL может быть дамп?

Дампы, записанные pg_dump и pg_dumpall из PostgreSQL 10 и новее, со строками COPY или INSERT. Каждый тестовый дамп создан в PostgreSQL 13 и 18 и сверен с источником ячейка за ячейкой.

Сохраняются ли значения serial и identity?

Да. Столбец serial или identity каждой таблицы становится столбцом IDENTITY, каждая строка сохраняет свой id, а следующий id идет после наибольшего. SQL Server нумерует один столбец на таблицу, поэтому любой другой сохраняет значения без счетчика.

Что происходит с массивами, enum и другими типами PostgreSQL?

Массивы становятся массивами JSON, логические значения - bit, uuid - uniqueidentifier, а timestamp с часовым поясом - datetimeoffset. Текст сравнивается точно, как в PostgreSQL, а citext - без учета регистра. Диапазоны, геометрические и составные типы сохраняют текст PostgreSQL.

А функции, триггеры и представления?

Они перечислены в отчете по имени и не конвертируются, потому что каждая база данных пишет их на своем языке.

На каких версиях SQL Server загружается скрипт?

SQL Server с 2017 по 2025. Один и тот же скрипт загружается на каждой из них и останавливается на первой ошибке, если что-то пойдет не так.