---
title: "在浏览器中将 PostgreSQL 迁移到 SQL Server"
description: "将 PostgreSQL 数据库迁移到 SQL Server：把 pg_dump 文件转换为表、键和数据相同的脚本，并报告每项更改。"
canonical: https://intosql.com/zh-cn/postgresql-to-sql-server
last_updated: 2026-10-15
---

# 在浏览器中将 PostgreSQL 迁移到 SQL Server

拖入由 pg_dump 或 pg_dumpall 生成的纯文本转储（.sql 或 .sql.gz），即可下载包含相同表、键、索引和数据的 SQL Server 脚本。SQL Server 无法原样存储的每个值，以及它不支持的每个对象，都会在报告中列出。

[PostgreSQL 到 SQL Server 迁移指南](https://intosql.com/docs/migrations/postgresql-to-sql-server)

[PostgreSQL 到 SQL Server 的数据类型](https://intosql.com/docs/types/postgresql-to-sql-server)

## 从 PostgreSQL 到 SQL Server 的变化

每一行是转换器应用的一条规则，以及该规则更改你的数据时在报告中写入的记录。

| 在 PostgreSQL 中 | 在 SQL Server 中 | 报告记录 |
| --- | --- | --- |
| boolean | bit |  |
| varchar(n), char(n), text | nvarchar(n)；text 为 nvarchar(max)，用于键且所有值都能容纳时为 nvarchar(450) |  |
| text comparison | 精确比较 (Latin1_General_100_BIN2)；citext 不区分大小写 (Latin1_General_100_CI_AS_SC) |  |
| numeric(p,s) past 38 digits; numeric without a precision | nvarchar；值不超过 38 位时为按值调整的 decimal(p,s) | `decimal_as_text` |
| money | decimal(19,2) | `type_replaced` |
| interval | nvarchar(100)，存放 PostgreSQL 的文本 | `type_replaced` |
| arrays (integer[], text[]...) | 存放 JSON 数组的 nvarchar(max) | `type_replaced` |
| ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types | nvarchar(max)，存放 PostgreSQL 的文本 | `type_replaced` |
| json, jsonb | nvarchar(max) |  |
| timestamp | datetime2 |  |
| timestamp with time zone | UTC 的 datetimeoffset |  |
| time with 24:00:00 in it | nvarchar(17) | `time_as_interval` |
| infinity, -infinity and BC dates | NULL | `date_out_of_range` |
| NaN and Infinity in numeric, real and double precision | NULL | `invalid_value_null` |
| NOT NULL columns with values that become 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 |  |
| bytea | varbinary(max) |  |
| bit(n), bit varying | 一位时为 bit；不超过 63 位时为 bigint；更长则为文本数字 |  |
| oid, xid, cid | bigint，并带有不能为负数的 CHECK |  |
| serial, identity | IDENTITY，从最大的 id 之后继续 |  |
| a second serial or identity column in a table | 普通整数 | `counter_dropped` |
| sequences not owned by a column | CREATE SEQUENCE ... AS bigint，带下一个值 |  |
| generated columns | 计算列，源数据存储它们时为 PERSISTED |  |
| generated columns with functions SQL Server lacks | 带有这些值的普通列 | `generated_not_translated` |
| defaults with functions SQL Server lacks, and defaults from a sequence | 无默认值 | `default_not_translated` |
| CHECK constraints | 已转换，内联在 CREATE TABLE 中 |  |
| CHECK constraints with functions SQL Server lacks | 不创建 | `check_skipped` |
| CHECK ... NOT VALID | 不创建 | `check_not_valid` |
| gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a key | 不创建 | `index_skipped` |
| foreign keys | 在数据之后以 WITH NOCHECK 添加，然后检查，有孤立行时给出警告 |  |
| ON DELETE or ON UPDATE that cascades in a cycle or along a second path | NO ACTION | `foreign_key_action_dropped` |
| foreign keys to tables the dump doesn't create | 不创建 | `foreign_key_skipped` |
| partitioned tables | 单个表，包含每个分区的行 | `partitions_dropped` |
| views, functions, procedures, triggers, rules, policies, extensions and types | 在报告中列出 | `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) | `unknown_type` |
| text that isn't valid in its encoding | 错误的字节变为替换字符 | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | 按原样复制 | `mojibake_suspected` |

## 将脚本导入 SQL Server

脚本先创建表、复制行，再添加键、索引和外键，因此导入速度快，并会在遇到第一个错误时停止。

```shell
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）可用 pg_restore -f dump.sql 转为 SQL，无需数据库服务器。
- --no-owner --no-privileges 会省略角色和授权，转换器本来也会跳过它们，因此转储更小。
- pg_dumpall 将每个数据库转储到一个文件中；每个数据库的表名前会加上该数据库名，因此不会冲突。

## 哪些内容不会转换

视图、物化视图、函数、存储过程、触发器、规则、行安全策略、扩展和类型都是用 PostgreSQL 自己的语言编写的。它们会按名称在报告中列出，绝不会被悄悄丢弃，以便你为 SQL Server 重写。

## 关于 PostgreSQL 转 SQL Server 的问题

### 我的转储会被上传吗？

不会。转换器在你的浏览器中运行，分块从磁盘读取转储，因此转储不会离开你的电脑。桌面应用和命令行也在你的电脑上转换。

### 转储可以多大？

转换器从不把整个转储放进内存：它按范围读取文件两次，边读边写出脚本。几 GB 的转储可以在浏览器、桌面应用和命令行中转换。

### 它能读取 pg_dump -Fc 归档吗？

不能直接读取：custom 归档是二进制格式。pg_restore -f dump.sql dump.backup 会将其转为转换器读取的纯 SQL，无需连接服务器。转换器收到归档时会给出提示。

### 转储可以来自哪些 PostgreSQL 版本？

由 PostgreSQL 10 及更高版本的 pg_dump 和 pg_dumpall 写出的转储，行可以是 COPY 或 INSERT。每个测试转储都来自 PostgreSQL 13 和 18，并与其源数据逐个单元格比较。

### serial 和标识列的值会保留吗？

会。每个表的 serial 或标识列变为 IDENTITY 列，每行保留其 id，下一个 id 从最大的 id 之后继续。SQL Server 每个表只为一列计数，因此其他列保留其值，不带计数器。

### 数组、enum 和其他 PostgreSQL 类型会怎样处理？

数组变为 JSON 数组，布尔值变为 bit，uuid 变为 uniqueidentifier，带时区的时间戳变为 datetimeoffset。文本像在 PostgreSQL 中一样精确比较，citext 则不区分大小写。range、几何类型和复合类型保留 PostgreSQL 的文本。

### 函数、触发器和视图怎么处理？

它们会按名称在报告中列出，但不会转换，因为每种数据库都用自己的语言编写它们。

### 脚本可以导入哪些 SQL Server 版本？

SQL Server 2017 到 2025。同一个脚本在每个版本上都能导入，如有问题会在第一个错误处停止。

## 从 PostgreSQL

- [PostgreSQL 到 PostgreSQL](https://intosql.com/zh-cn/postgresql-to-postgresql)
- [PostgreSQL 到 MySQL](https://intosql.com/zh-cn/postgresql-to-mysql)
- [PostgreSQL 到 MariaDB](https://intosql.com/zh-cn/postgresql-to-mariadb)
- [PostgreSQL 到 SQLite](https://intosql.com/zh-cn/postgresql-to-sqlite)
- [PostgreSQL 到 Oracle](https://intosql.com/zh-cn/postgresql-to-oracle)

## 到 SQL Server

- [MySQL 到 SQL Server](https://intosql.com/zh-cn/mysql-to-sql-server)
- [MariaDB 到 SQL Server](https://intosql.com/zh-cn/mariadb-to-sql-server)
- [SQL Server 到 SQL Server](https://intosql.com/zh-cn/sql-server-to-sql-server)
- [SQLite 到 SQL Server](https://intosql.com/zh-cn/sqlite-to-sql-server)
- [Oracle 到 SQL Server](https://intosql.com/zh-cn/oracle-to-sql-server)

## 指南和所有组合

- [SQL Server 到 PostgreSQL](https://intosql.com/zh-cn/sql-server-to-postgresql)
- [PostgreSQL 到 SQL Server 迁移指南](https://intosql.com/docs/migrations/postgresql-to-sql-server)
- [PostgreSQL 到 SQL Server 的数据类型](https://intosql.com/docs/types/postgresql-to-sql-server)
- [所有数据库组合](https://intosql.com/zh-cn/database-migration)
