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.
Đã chuyển đổi 18 hàng, 2 bản sửa, không hàng nào bị từ chối
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 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 hàng1
10 cột 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)
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
- "tags" của customers là text[], kiểu SQL Server không có, nên là nvarchar(max) với cùng giá trị.
- "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 PostgreSQL | Trong SQL Server | Dòng báo cáo |
|---|---|---|
| boolean | bitbit 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ừ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 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. | 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. | type_replaced |
| interval | nvarchar(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 types | nvarchar(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, jsonb | nvarchar(max)Các hàm JSON của SQL Server đọc JSON từ văn bản. | |
| timestamp | datetime2timestamp không có múi giờ là thời gian theo đồng hồ, giống datetime2. | |
| timestamp with time zone | datetimeoffset 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 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ó. | time_as_interval |
| infinity, -infinity and BC dates | NULLSQL 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 precision | NULLSố 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 NULL | bỏ 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 types | nvarchar 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 labels | nvarchar 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, macaddr | uniqueidentifier; địa chỉ dạng nvarcharuniqueidentifier 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 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, cid | bigint kèm CHECK không âmbigint chứa được mọi giá trị. | |
| serial, identity | IDENTITY, 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 table | mộ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 column | CREATE 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 columns | cộ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 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. | generated_not_translated |
| defaults with functions SQL Server lacks, and defaults from a sequence | khô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 lacks | khô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 VALID | khô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 key | khô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 keys | sau 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 path | NO 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 create | khô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 tables | mộ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 values | NULLTrì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 know | nvarchar(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 encoding | byte 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.sqlKhó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ố.