Chuyển đến nội dung
Trang chủ IntoSQL

Chuyển PostgreSQL sang SQL Server

Thả bản dump dạng plain từ pg_dump hoặc pg_dumpall, dạng .sql hoặc .sql.gz, và tải xuống tập lệnh SQL Server với cùng bảng, khóa, chỉ mục và dữ liệu. Mọi giá trị SQL Server không chứa được nguyên trạng, và mọi đối tượng nó không hỗ trợ, đều được liệt kê trong báo cáo.

Tệp của bạn
sqlshop_2024_postgres.sqlTệp mẫu, 6,2 kB
Cơ sở dữ liệu của bạn

Đã chuyển đổi 18 hàng, 2 bản sửa, không hàng nào bị từ chối

Hiển thị

Các bảng trong shop_2024_postgres.sqlBản dump PostgreSQL 18.6 · do pg_dump ghi · utf8mb4

  • customers8 hàng1
    8 cột
    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 hàng1
    10 cột
    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)

Không được chuyển đổi

  • Khung nhìn paid_orders

Mỗi cơ sở dữ liệu viết các đối tượng này bằng ngôn ngữ riêng. Hãy viết lại chúng cho 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

Bản sửa

  1. "tags" của customers là text[], kiểu SQL Server không có, nên là nvarchar(max) với cùng giá trị.
  2. "delivery" của orders là interval, kiểu SQL Server không có, nên là nvarchar(100) với cùng giá trị.

Cần xem lại

  • 1 khung nhìn, trình kích hoạt, thủ tục hoặc sự kiện không được chuyển đổi; báo cáo liệt kê từng mục. Hãy tạo lại chúng thủ công trong SQL Server.
  • Giá trị mặc định của "tags" trong customers không viết được cho SQL Server (a value its type can't hold), nên cột không có giá trị mặc định. Hãy thêm giá trị mặc định thủ công nếu hàng mới cần nó.
  • Chỉ mục idx_orders_details trên orders dùng một biểu thức không viết được cho SQL Server (an index on an expression), nên không được tạo. Hãy tạo chỉ mục thủ công nếu truy vấn cần nó.
  • 1 giá trị trong "shipped_at" của orders là ngày mà SQL Server không lưu được, như infinity, nên chúng là NULL. SQL Server lưu năm từ 1 đến 9999, không có vô cực; hãy thay các ngày đó trong nguồn nếu chúng quan trọng.

Tệp được chuyển đổi ngay trên máy tính này và không bao giờ được tải lên.

Mẫu khác:

Những gì thay đổi từ PostgreSQL sang SQL Server

Mỗi hàng là một quy tắc trình chuyển đổi áp dụng, kèm dòng báo cáo được ghi khi quy tắc thay đổi dữ liệu của bạn.

  • boolean

    bit

    bit lưu true là 1 và false là 0.

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

    nvarchar(n); text dạng nvarchar(max), hoặc nvarchar(450) khi dùng trong khóa và mọi giá trị vừa

    nvarchar chứa được mọi ký tự. SQL Server không lập chỉ mục được nvarchar(max), nên văn bản trong khóa có kích thước vừa với khóa.

  • text comparison

    chính xác (Latin1_General_100_BIN2); citext không phân biệt hoa thường (Latin1_General_100_CI_AS_SC)

    Collation thường dùng của SQL Server không phân biệt hoa thường, còn văn bản của PostgreSQL thì có, nên mỗi cột ghi rõ cách so sánh và khóa duy nhất vẫn phân biệt đúng các hàng.

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

    nvarchar; decimal(p,s) vừa với giá trị khi chúng vừa 38 chữ số

    decimal của SQL Server chứa 38 chữ số. numeric không có độ chính xác nhận decimal hẹp nhất vừa với giá trị; số rộng hơn được giữ dạng văn bản để mọi chữ số vẫn chính xác.

    Dòng báo cáo: decimal_as_text

  • money

    decimal(19,2)

    money của SQL Server nhỏ hơn của PostgreSQL và có bốn chữ số thập phân; decimal(19,2) chứa mọi số tiền, không kèm ký hiệu tiền tệ mà locale của máy chủ đã thêm.

    Dòng báo cáo: type_replaced

  • interval

    nvarchar(100) với văn bản của PostgreSQL

    SQL Server không có kiểu interval; văn bản giữ mọi phần.

    Dòng báo cáo: type_replaced

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

    nvarchar(max) chứa mảng JSON

    SQL Server không có mảng. Mảng JSON giữ mọi phần tử và NULL, và OPENJSON đọc được nó.

    Dòng báo cáo: type_replaced

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

    nvarchar(max) với văn bản của PostgreSQL

    SQL Server không có kiểu tương đương, nên mỗi giá trị giữ văn bản PostgreSQL đã ghi.

    Dòng báo cáo: type_replaced

  • json, jsonb

    nvarchar(max)

    Các hàm JSON của SQL Server đọc JSON từ văn bản.

  • timestamp

    datetime2

    timestamp không có múi giờ là thời gian theo đồng hồ, giống datetime2.

  • timestamp with time zone

    datetimeoffset theo UTC

    datetimeoffset giữ thời điểm; mỗi giá trị được ghi theo UTC, cùng một thời điểm dù bản dump ghi độ lệch nào.

  • time with 24:00:00 in it

    nvarchar(17)

    time của SQL Server kết thúc ở 23:59:59.9999999, nên cột chứa 24:00:00 giữ văn bản của nó.

    Dòng báo cáo: time_as_interval

  • infinity, -infinity and BC dates

    NULL

    SQL Server lưu năm từ 1 đến 9999, không có vô cực. Các giá trị đó trở thành NULL và báo cáo đếm số lượng.

    Dòng báo cáo: date_out_of_range

  • NaN and Infinity in numeric, real and double precision

    NULL

    Số của SQL Server không có NaN hay Infinity, nên các giá trị đó trở thành NULL và báo cáo đếm số lượng.

    Dòng báo cáo: invalid_value_null

  • NOT NULL columns with values that become NULL

    bỏ NOT NULL

    Cột có giá trị phải chuyển thành NULL không thể giữ NOT NULL, nếu không quá trình nạp sẽ dừng.

    Dòng báo cáo: not_null_relaxed

  • enum types

    nvarchar kèm CHECK các nhãn

    Văn bản kèm ràng buộc kiểm tra giữ đúng các giá trị.

  • enum columns holding values outside their labels

    nvarchar không có ràng buộc kiểm tra

    Giá trị không có trong các nhãn sẽ vi phạm ràng buộc kiểm tra, nên ràng buộc không được tạo.

    Dòng báo cáo: enum_check_skipped

  • uuid, inet, cidr, macaddr

    uniqueidentifier; địa chỉ dạng nvarchar

    uniqueidentifier là UUID của SQL Server; địa chỉ được giữ dạng văn bản.

  • bytea

    varbinary(max)

    Byte vẫn là byte.

  • bit(n), bit varying

    bit cho một bit; bigint đến 63 bit; dài hơn là chữ số dạng text

    Một bit đơn là có hoặc không; chuỗi bit dài hơn được lưu là số do các bit tạo thành.

  • oid, xid, cid

    bigint kèm CHECK không âm

    bigint chứa được mọi giá trị.

  • serial, identity

    IDENTITY, tiếp tục sau id lớn nhất

    Các id đã sao chép được nạp với IDENTITY_INSERT, và bộ đếm tiếp tục sau id lớn nhất hoặc giá trị kế tiếp của sequence, tùy giá trị nào lớn hơn.

  • a second serial or identity column in a table

    một số nguyên thường

    SQL Server đếm một cột IDENTITY mỗi bảng; cột khác giữ giá trị mà không có bộ đếm.

    Dòng báo cáo: counter_dropped

  • sequences not owned by a column

    CREATE SEQUENCE ... AS bigint, kèm giá trị tiếp theo

    SQL Server có sequence với cùng các tùy chọn; mỗi sequence tiếp tục từ chỗ bản dump dừng lại.

  • generated columns

    cột tính toán, PERSISTED khi nguồn lưu chúng

    SQL Server tính chúng theo cùng hai cách.

  • generated columns with functions SQL Server lacks

    một cột thường với các giá trị

    Công thức không viết được cho SQL Server để lại một cột thường với giá trị của bản dump và một dòng trong báo cáo.

    Dòng báo cáo: generated_not_translated

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

    không có giá trị mặc định

    Giá trị mặc định không viết được cho SQL Server sẽ bị bỏ và được báo cáo.

    Dòng báo cáo: default_not_translated

  • CHECK constraints

    được chuyển đổi, viết trực tiếp trong CREATE TABLE

    Ràng buộc viết trực tiếp được kiểm tra khi nạp từng hàng.

  • CHECK constraints with functions SQL Server lacks

    không được tạo

    Ràng buộc kiểm tra không viết được cho SQL Server sẽ bị bỏ và được báo cáo.

    Dòng báo cáo: check_skipped

  • CHECK ... NOT VALID

    không được tạo

    PostgreSQL chưa bao giờ kiểm tra các hàng có từ trước, nên chúng có thể vi phạm ràng buộc.

    Dòng báo cáo: check_not_valid

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

    không được tạo

    SQL Server lập chỉ mục trên cột, không trên biểu thức, và không trên nvarchar(max).

    Dòng báo cáo: index_skipped

  • foreign keys

    sau dữ liệu WITH NOCHECK, rồi kiểm tra kèm cảnh báo về hàng mồ côi

    Khóa được tạo sau các hàng và kiểm tra sau cùng; hàng không có hàng cha khiến khóa ở trạng thái chưa kiểm tra kèm cảnh báo thay vì dừng quá trình nạp.

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

    NO ACTION

    SQL Server từ chối cascade có thể đến một bảng hai lần; PostgreSQL cho phép.

    Dòng báo cáo: foreign_key_action_dropped

  • foreign keys to tables the dump doesn't create

    không được tạo

    Khóa không thể tham chiếu tới bảng không tồn tại.

    Dòng báo cáo: foreign_key_skipped

  • partitioned tables

    một bảng chứa các hàng của mọi phân vùng

    Các hàng giữ nguyên; hãy phân vùng lại bảng trong SQL Server nếu cần.

    Dòng báo cáo: partitions_dropped

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

    được liệt kê trong báo cáo

    Mã của chúng viết bằng ngôn ngữ của PostgreSQL, nên được liệt kê để bạn tạo lại.

    Dòng báo cáo: not_converted_objects

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

    kiểu suy ra từ giá trị

    Bản dump chỉ có dữ liệu thì chỉ có các hàng, nên kiểu được suy ra từ giá trị.

    Dòng báo cáo: no_schema

  • expressions in INSERT values

    NULL

    Trình chuyển đổi không chạy cơ sở dữ liệu thì không tính được chúng.

    Dòng báo cáo: expression_value

  • types IntoSQL doesn't know

    nvarchar(max)

    Văn bản chứa được mọi giá trị; hãy đổi kiểu sau khi nạp.

    Dòng báo cáo: unknown_type

  • text that isn't valid in its encoding

    byte lỗi thành ký tự thay thế

    nvarchar chứa văn bản Unicode.

    Dòng báo cáo: invalid_utf8_replaced

  • text decoded twice (ñ)

    sao chép nguyên trạng

    Bản dump chứa đúng các ký tự này, nên chúng được sao chép; báo cáo chỉ ra chúng.

    Dòng báo cáo: mojibake_suspected

Trong PostgreSQLTrong SQL ServerDòng báo cáo
booleanbitbit lưu true là 1 và false là 0.
varchar(n), char(n), textnvarchar(n); text dạng nvarchar(max), hoặc nvarchar(450) khi dùng trong khóa và mọi giá trị vừanvarchar chứa được mọi ký tự. SQL Server không lập chỉ mục được nvarchar(max), nên văn bản trong khóa có kích thước vừa với khóa.
text comparisonchính xác (Latin1_General_100_BIN2); citext không phân biệt hoa thường (Latin1_General_100_CI_AS_SC)Collation thường dùng của SQL Server không phân biệt hoa thường, còn văn bản của PostgreSQL thì có, nên mỗi cột ghi rõ cách so sánh và khóa duy nhất vẫn phân biệt đúng các hàng.
numeric(p,s) past 38 digits; numeric without a precisionnvarchar; decimal(p,s) vừa với giá trị khi chúng vừa 38 chữ sốdecimal của SQL Server chứa 38 chữ số. numeric không có độ chính xác nhận decimal hẹp nhất vừa với giá trị; số rộng hơn được giữ dạng văn bản để mọi chữ số vẫn chính xác.decimal_as_text
moneydecimal(19,2)money của SQL Server nhỏ hơn của PostgreSQL và có bốn chữ số thập phân; decimal(19,2) chứa mọi số tiền, không kèm ký hiệu tiền tệ mà locale của máy chủ đã thêm.type_replaced
intervalnvarchar(100) với văn bản của PostgreSQLSQL Server không có kiểu interval; văn bản giữ mọi phần.type_replaced
arrays (integer[], text[]...)nvarchar(max) chứa mảng JSONSQL Server không có mảng. Mảng JSON giữ mọi phần tử và NULL, và OPENJSON đọc được nó.type_replaced
ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension typesnvarchar(max) với văn bản của PostgreSQLSQL Server không có kiểu tương đương, nên mỗi giá trị giữ văn bản PostgreSQL đã ghi.type_replaced
json, jsonbnvarchar(max)Các hàm JSON của SQL Server đọc JSON từ văn bản.
timestampdatetime2timestamp không có múi giờ là thời gian theo đồng hồ, giống datetime2.
timestamp with time zonedatetimeoffset theo UTCdatetimeoffset giữ thời điểm; mỗi giá trị được ghi theo UTC, cùng một thời điểm dù bản dump ghi độ lệch nào.
time with 24:00:00 in itnvarchar(17)time của SQL Server kết thúc ở 23:59:59.9999999, nên cột chứa 24:00:00 giữ văn bản của nó.time_as_interval
infinity, -infinity and BC datesNULLSQL Server lưu năm từ 1 đến 9999, không có vô cực. Các giá trị đó trở thành NULL và báo cáo đếm số lượng.date_out_of_range
NaN and Infinity in numeric, real and double precisionNULLSố của SQL Server không có NaN hay Infinity, nên các giá trị đó trở thành NULL và báo cáo đếm số lượng.invalid_value_null
NOT NULL columns with values that become NULLbỏ NOT NULLCột có giá trị phải chuyển thành NULL không thể giữ NOT NULL, nếu không quá trình nạp sẽ dừng.not_null_relaxed
enum typesnvarchar kèm CHECK các nhãnVăn bản kèm ràng buộc kiểm tra giữ đúng các giá trị.
enum columns holding values outside their labelsnvarchar không có ràng buộc kiểm traGiá trị không có trong các nhãn sẽ vi phạm ràng buộc kiểm tra, nên ràng buộc không được tạo.enum_check_skipped
uuid, inet, cidr, macaddruniqueidentifier; địa chỉ dạng nvarcharuniqueidentifier là UUID của SQL Server; địa chỉ được giữ dạng văn bản.
byteavarbinary(max)Byte vẫn là byte.
bit(n), bit varyingbit cho một bit; bigint đến 63 bit; dài hơn là chữ số dạng textMột bit đơn là có hoặc không; chuỗi bit dài hơn được lưu là số do các bit tạo thành.
oid, xid, cidbigint kèm CHECK không âmbigint chứa được mọi giá trị.
serial, identityIDENTITY, tiếp tục sau id lớn nhấtCác id đã sao chép được nạp với IDENTITY_INSERT, và bộ đếm tiếp tục sau id lớn nhất hoặc giá trị kế tiếp của sequence, tùy giá trị nào lớn hơn.
a second serial or identity column in a tablemột số nguyên thườngSQL Server đếm một cột IDENTITY mỗi bảng; cột khác giữ giá trị mà không có bộ đếm.counter_dropped
sequences not owned by a columnCREATE SEQUENCE ... AS bigint, kèm giá trị tiếp theoSQL Server có sequence với cùng các tùy chọn; mỗi sequence tiếp tục từ chỗ bản dump dừng lại.
generated columnscột tính toán, PERSISTED khi nguồn lưu chúngSQL Server tính chúng theo cùng hai cách.
generated columns with functions SQL Server lacksmột cột thường với các giá trịCông thức không viết được cho SQL Server để lại một cột thường với giá trị của bản dump và một dòng trong báo cáo.generated_not_translated
defaults with functions SQL Server lacks, and defaults from a sequencekhông có giá trị mặc địnhGiá trị mặc định không viết được cho SQL Server sẽ bị bỏ và được báo cáo.default_not_translated
CHECK constraintsđược chuyển đổi, viết trực tiếp trong CREATE TABLERàng buộc viết trực tiếp được kiểm tra khi nạp từng hàng.
CHECK constraints with functions SQL Server lackskhông được tạoRàng buộc kiểm tra không viết được cho SQL Server sẽ bị bỏ và được báo cáo.check_skipped
CHECK ... NOT VALIDkhông được tạoPostgreSQL chưa bao giờ kiểm tra các hàng có từ trước, nên chúng có thể vi phạm ràng buộc.check_not_valid
gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a keykhông được tạoSQL Server lập chỉ mục trên cột, không trên biểu thức, và không trên nvarchar(max).index_skipped
foreign keyssau dữ liệu WITH NOCHECK, rồi kiểm tra kèm cảnh báo về hàng mồ côiKhóa được tạo sau các hàng và kiểm tra sau cùng; hàng không có hàng cha khiến khóa ở trạng thái chưa kiểm tra kèm cảnh báo thay vì dừng quá trình nạp.
ON DELETE or ON UPDATE that cascades in a cycle or along a second pathNO ACTIONSQL Server từ chối cascade có thể đến một bảng hai lần; PostgreSQL cho phép.foreign_key_action_dropped
foreign keys to tables the dump doesn't createkhông được tạoKhóa không thể tham chiếu tới bảng không tồn tại.foreign_key_skipped
partitioned tablesmột bảng chứa các hàng của mọi phân vùngCác hàng giữ nguyên; hãy phân vùng lại bảng trong SQL Server nếu cần.partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and typesđược liệt kê trong báo cáoMã của chúng viết bằng ngôn ngữ của PostgreSQL, nên được liệt kê để bạn tạo lại.not_converted_objects
dumps without CREATE TABLE (--data-only)kiểu suy ra từ giá trịBản dump chỉ có dữ liệu thì chỉ có các hàng, nên kiểu được suy ra từ giá trị.no_schema
expressions in INSERT valuesNULLTrình chuyển đổi không chạy cơ sở dữ liệu thì không tính được chúng.expression_value
types IntoSQL doesn't knownvarchar(max)Văn bản chứa được mọi giá trị; hãy đổi kiểu sau khi nạp.unknown_type
text that isn't valid in its encodingbyte lỗi thành ký tự thay thếnvarchar chứa văn bản Unicode.invalid_utf8_replaced
text decoded twice (ñ)sao chép nguyên trạngBản dump chứa đúng các ký tự này, nên chúng được sao chép; báo cáo chỉ ra chúng.mojibake_suspected

Nạp tập lệnh vào SQL Server

Tập lệnh tạo bảng, sao chép các hàng, rồi thêm khóa, chỉ mục và khóa ngoại, nên nạp nhanh và dừng ở lỗi đầu tiên.

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

Khóa ngoại được thêm với WITH NOCHECK rồi được kiểm tra. Nếu một hàng trỏ tới hàng không tồn tại, tập lệnh cho biết ràng buộc nào và để nó ở trạng thái chưa kiểm tra, thay vì thất bại giữa chừng.

Với bản dump lớn, hãy chạy sqlcmd trên cùng máy với máy chủ. Mỗi lô tối đa 1000 hàng được commit riêng, nên nhật ký giao dịch luôn nhỏ.

Tạo bản dump PostgreSQL để có kết quả tốt nhất

Trình chuyển đổi đọc những gì bản dump chứa. Các tùy chọn sau giữ lại nhiều dữ liệu hơn trong đó:

  • --format=plain, mặc định của pg_dump, ghi ra SQL. Kho lưu trữ custom hoặc directory (-Fc, -Fd) thành SQL bằng pg_restore -f dump.sql, không cần máy chủ cơ sở dữ liệu.
  • --no-owner --no-privileges bỏ vai trò và quyền, những thứ trình chuyển đổi vốn bỏ qua, nên bản dump nhỏ hơn.
  • pg_dumpall dump mọi cơ sở dữ liệu vào một tệp; bảng của mỗi cơ sở dữ liệu có tên của nó ở đầu, nên không có gì trùng.

Những gì không được chuyển đổi

Khung nhìn, khung nhìn cụ thể hóa, hàm, thủ tục, trình kích hoạt, quy tắc, chính sách bảo mật cấp hàng, tiện ích mở rộng và kiểu được viết bằng ngôn ngữ riêng của PostgreSQL. Chúng được liệt kê theo tên trong báo cáo, không bao giờ bị bỏ âm thầm, để bạn viết lại cho SQL Server.

Câu hỏi về PostgreSQL sang SQL Server

Chưa có câu trả lời ở đây? Hãy viết cho chúng tôi từ trang liên hệ, sẽ có người trả lời. Trang liên hệ

Bản dump của tôi có bị tải lên không?

Không. Trình chuyển đổi chạy trong trình duyệt và đọc bản dump từ ổ đĩa theo từng phần, nên nó không bao giờ rời khỏi máy tính của bạn. Ứng dụng máy tính và dòng lệnh cũng chuyển đổi ngay trên máy tính của bạn.

Bản dump có thể lớn đến đâu?

Trình chuyển đổi không bao giờ giữ toàn bộ bản dump trong bộ nhớ: nó đọc tệp hai lần, theo từng đoạn, và ghi tập lệnh trong lúc đọc. Bản dump nhiều gigabyte vẫn chuyển đổi được trong trình duyệt, trong ứng dụng máy tính và bằng dòng lệnh.

Nó có đọc được kho lưu trữ pg_dump -Fc không?

Không trực tiếp: kho lưu trữ custom là định dạng nhị phân. pg_restore -f dump.sql dump.backup chuyển nó thành SQL dạng plain mà trình chuyển đổi đọc được, không cần kết nối máy chủ. Trình chuyển đổi sẽ báo khi nhận một kho lưu trữ.

Bản dump có thể đến từ những phiên bản PostgreSQL nào?

Bản dump do pg_dump và pg_dumpall ghi từ PostgreSQL 10 trở lên, với các hàng COPY hoặc INSERT. Mọi bản dump thử nghiệm đến từ PostgreSQL 13 và 18 và được so với nguồn từng ô một.

Giá trị serial và identity có được giữ không?

Có. Cột serial hoặc identity của mỗi bảng trở thành cột IDENTITY, mọi hàng giữ id của nó, và id tiếp theo tiếp tục sau id lớn nhất. SQL Server đếm một cột mỗi bảng, nên cột khác giữ giá trị mà không có bộ đếm.

Mảng, enum và các kiểu PostgreSQL khác sẽ ra sao?

Mảng thành mảng JSON, boolean thành bit, uuid thành uniqueidentifier, và timestamp có múi giờ thành datetimeoffset. Văn bản so sánh chính xác, như trong PostgreSQL, và citext không phân biệt hoa thường. Range, kiểu hình học và kiểu composite giữ văn bản của PostgreSQL.

Còn hàm, trình kích hoạt và khung nhìn thì sao?

Chúng được liệt kê theo tên trong báo cáo và không được chuyển đổi, vì mỗi cơ sở dữ liệu viết chúng bằng ngôn ngữ riêng.

Tập lệnh nạp được trên những phiên bản SQL Server nào?

SQL Server 2017 đến 2025. Cùng một tập lệnh nạp được trên từng phiên bản, và dừng ở lỗi đầu tiên nếu có sự cố.