Converta SQL Server para PostgreSQL
Solte o script que o Generate Scripts do SSMS escreve com schema e dados, em .sql ou .sql.gz, UTF-16 ou UTF-8, e baixe um script do PostgreSQL com as mesmas tabelas, chaves, índices e dados. Cada valor que o PostgreSQL não aceita como está, e cada objeto que ele não traz, aparece no relatório.
18 linhas convertidas, 3 correções, nenhuma rejeitada
Tabelas em shop_2024_sqlserver.sqlDump do SQL Server · gerado por SQL Server Management Objects · utf-8
orders10 linhas2
11 colunas id integer not null customer_id integer not null status varchar(10) not null total numeric(19,4) not null items smallint not null ordered_at timestamp(0) not null shipped_at timestamp(6) note text details text order_ref uuid not null total_with_tax numeric(12,2) customers8 linhas1
8 colunas id integer not null name varchar(100) not null email varchar(200) not null country varchar(2) not null is_active boolean not null signed_up date created_at timestamptz(0) not null row_version bytea
Não convertidos
- Visão paid_orders
- Gatilho orders_no_negative
Cada banco de dados escreve estes objetos na sua própria linguagem. Reescreva-os para o PostgreSQL.
-- Written by IntoSQL from a SQL Server dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';
CREATE TABLE orders (
id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_id integer NOT NULL,
status varchar(10) DEFAULT 'pending' NOT NULL,
total numeric(19,4) NOT NULL,
items smallint DEFAULT 1 NOT NULL,
ordered_at timestamp(0) NOT NULL,
shipped_at timestamp(6),
note text,
details text,
order_ref uuid DEFAULT (gen_random_uuid()::text) NOT NULL,
total_with_tax numeric(12,2) GENERATED ALWAYS AS ((cast(total * (1.16) AS numeric(12,2)))::numeric(12,2)) STORED,
CONSTRAINT orders_items_check CHECK (items >= 0),
CONSTRAINT orders_check2 CHECK (status = 'cancelled' OR status = 'shipped' OR status = 'paid' OR status = 'pending'),
CONSTRAINT orders_check3 CHECK (total >= (0))
);
CREATE TABLE customers (
id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name varchar(100) NOT NULL,
email varchar(200) NOT NULL,
country varchar(2) DEFAULT 'US' NOT NULL,
is_active boolean DEFAULT true NOT NULL,
signed_up date,
created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
row_version bytea
);
COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1 Ana Martínez ana@example.com MX t 2023-01-15 2023-01-15 10:24:00.000000+00:00
2 Zoë Müller zoe@example.de DE t 2023-02-03 2023-02-03 08:11:42.000000+00:00
3 José Peña jose@example.es ES f 2023-03-21 2023-03-21 19:05:17.000000+00:00
4 李雷 lilei@example.cn CN t 2023-05-09 2023-05-09 02:40:00.000000+00:00
5 Noah O'Brien noah@example.ie IE t \N 2023-06-30 14:00:00.000000+00:00
6 Amélie Laurent amelie@example.fr FR t 2024-01-02 2024-01-02 09:30:00.000000+00:00
7 Ravi Patel ravi@example.in IN f 2024-02-29 2024-02-29 23:59:59.000000+00:00
8 Sofia Rossi 🌻 sofia@example.it IT t 2024-04-12 2024-04-12 12:12:12.000000+00:00
\.
COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) FROM stdin;
1 1 shipped 129.9000 3 2024-03-01T10:00:00.000000 2024-03-02T16:30:00.123456 \N {"gift": false} 0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f
2 2 paid 54.0000 1 2024-03-02T11:15:00.000000 \N Gift wrap 🎁 {"gift": true, "wrap": "red"} 1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70
3 1 cancelled 12.5000 1 2024-03-03T09:45:00.000000 \N Customer changed their mind \N 2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081
4 4 shipped 980.0000 12 2024-03-05T02:10:00.000000 2024-03-07T08:00:00.000000 请小心轻放 {"fragile": true} 3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192
5 5 pending 45.7500 2 2024-03-08T17:20:00.000000 \N Leave at the door; ring twice \N 4f1e806c-7d5b-4c2e-9a99-5e6f708192a3
6 6 shipped 310.4000 5 2024-03-10T13:00:00.000000 2024-03-11T09:00:00.000000 Fragile: "glass" {"fragile": true} 50f2917d-8e6c-4d3f-8baa-6f708192a3b4
7 8 paid 76.2000 2 2024-03-11T18:45:00.000000 \N \N \N 6103a28e-9f7d-4e40-9cbb-708192a3b4c5
8 2 shipped 19.9900 1 2024-03-12T08:00:00.000000 9999-12-31T23:59:59.999999 Shipped date set to the maximum by an old import \N 7214b39f-a08e-4f51-8dcc-8192a3b4c5d6
9 3 shipped 64.0000 2 2024-03-14T15:30:00.000000 2024-03-15T10:00:00.000000 Two parcels {"parcels": [1, 2]} 8325c4a0-b19f-4062-9edd-92a3b4c5d6e7
10 7 paid 1499.0000 1 2024-03-15T21:05:00.000000 \N C:\\Users\\ravi\\invoice.pdf \N 9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8
\.
-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_orders_customer ON orders (customer_id);
CREATE INDEX orders_idx_orders_status_date ON orders (status, ordered_at);
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_email ON customers (email);
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_email UNIQUE USING INDEX customers_email;
ALTER TABLE orders ADD CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
ALTER TABLE orders VALIDATE CONSTRAINT orders_fkey;
EXCEPTION WHEN foreign_key_violation THEN
RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'orders_fkey';
END $f$;
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 1), 2147483647)::bigint, false);
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1), 2147483647)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
Correções
- "items" de orders é sem sinal, então virou smallint com um CHECK de que não é negativa.
- "shipped_at" de orders é datetime2(7), com mais dígitos de segundo do que o PostgreSQL guarda, então vira timestamp(6) e os últimos dígitos são cortados.
- "row_version" de customers é uma versão de linha que o SQL Server define sozinho; o dump não tem valores para ela, então vira bytea e fica vazia.
Para revisar
- 6 colunas de texto comparam sem diferenciar maiúsculas na origem; o PostgreSQL compara de forma exata, então chaves únicas e buscas podem se comportar de outro jeito. Use uma collation ou um tipo de coluna sem diferenciação de maiúsculas nas colunas que precisarem.
- 2 visões, gatilhos, rotinas ou eventos não foram convertidos; o relatório lista cada um. Recrie-os manualmente no PostgreSQL.
- O CHECK check1 de orders não pode ser escrito para o PostgreSQL (function isjson), então não é criado. Escreva o CHECK manualmente se ele for importante.
- O índice idx_orders_pending de orders usa uma expressão que não pode ser escrita para o PostgreSQL (filtered index), então não é criado. Crie o índice manualmente se as consultas precisarem dele.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
O que muda do SQL Server para o PostgreSQL
Cada linha é uma regra que o conversor aplica, com a linha do relatório que ele escreve quando a regra muda algo nos seus dados.
bit
boolean
bit guarda 1 e 0, que são o true e o false do PostgreSQL.
tinyint
smallint com um CHECK de que não é negativo
O tinyint do SQL Server vai de 0 a 255; o menor inteiro do PostgreSQL tem sinal, então um CHECK mantém o intervalo.
Linha do relatório: unsigned_widened
char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text
varchar(n) e text
O text do PostgreSQL comporta qualquer caractere, então varchar e nvarchar são o mesmo tipo.
decimal(p,s), money, smallmoney
numeric(p,s); money como numeric(19,4)
Cada dígito é mantido, e money com suas quatro casas decimais.
datetime, datetime2, smalldatetime
timestamp(p)
Um datetime é a leitura de um relógio de parede, como um timestamp sem fuso horário.
datetime2(7), time(7) and datetimeoffset(7)
seis dígitos de segundo, o sétimo cortado
O PostgreSQL guarda microssegundos; o sétimo dígito (100 nanossegundos) é cortado, nunca arredondado, então nenhum valor passa para o segundo ou o dia seguinte.
Linha do relatório: fraction_cut
datetimeoffset
timestamptz, os mesmos instantes
timestamptz mantém o instante; o PostgreSQL o mostra no fuso horário da sessão em vez do fuso que cada valor tinha.
time
time(p)
Os mesmos horários do dia.
json (SQL Server 2025)
jsonb
Os mesmos valores JSON.
uniqueidentifier
uuid
Os mesmos identificadores, escritos em minúsculas.
binary, varbinary, image
bytea
Bytes continuam sendo bytes.
geometry, geography
bytea com os bytes próprios do SQL Server
O SSMS escreve valores espaciais na serialização do SQL Server, que é mantida byte a byte.
Linha do relatório: spatial_as_native
rowversion, timestamp
bytea, sem valores
O SQL Server define a versão de linha sozinho, e o SSMS não escreve valores para ela no script.
Linha do relatório: rowversion_empty
sql_variant, hierarchyid, vector
text
O PostgreSQL não tem um tipo equivalente; sql_variant mantém o texto de cada valor e hierarchyid o seu caminho, como /1/2/. xml continua xml.
Linha do relatório: type_replaced
collations that ignore case (_CI_)
comparação exata
O PostgreSQL compara texto de forma exata, então colunas que ignoravam maiúsculas no SQL Server agora diferenciam Ana de ana.
Linha do relatório: case_insensitive_collation
IDENTITY
GENERATED BY DEFAULT AS IDENTITY, continuando depois do maior id
Os ids copiados carregam como estão, e o contador continua depois do maior deles.
CREATE SEQUENCE
CREATE SEQUENCE com as mesmas opções
As sequências do PostgreSQL funcionam do mesmo jeito. O SSMS não escreve até onde uma sequência chegou, então ela começa onde foi criada.
computed columns
colunas geradas, STORED
O PostgreSQL 13 a 17 só armazena colunas geradas; a fórmula é a mesma, com CONCAT escrito para que NULL conte como vazio, como no SQL Server.
Linha do relatório: virtual_as_stored
computed columns with functions PostgreSQL lacks
uma coluna simples
Uma fórmula que não pode ser escrita para o PostgreSQL deixa uma coluna simples e uma linha no relatório; o SSMS não escreve valores para colunas computadas.
Linha do relatório: generated_not_translated
defaults with functions PostgreSQL lacks, and NEXT VALUE FOR
sem valor padrão
Um valor padrão que não pode ser escrito para o PostgreSQL fica de fora e é informado no relatório.
Linha do relatório: default_not_translated
CHECK constraints
traduzidos
Os mesmos CHECKs, testados à medida que cada linha carrega.
CHECK constraints with functions PostgreSQL lacks
não criado
Um CHECK que não pode ser escrito para o PostgreSQL fica de fora e é informado no relatório.
Linha do relatório: check_skipped
CHECK constraints added WITH NOCHECK or disabled
não criado
O SQL Server não aplica esses CHECKs, então as linhas podem violá-los.
Linha do relatório: check_not_enforced
filtered and columnstore indexes
não criado
O IntoSQL escreve índices b-tree sobre colunas; crie os outros de novo depois da carga.
Linha do relatório: index_skipped
foreign keys
chaves estrangeiras, depois das linhas
As linhas carregam em qualquer ordem, e as chaves as verificam depois.
foreign keys to tables the dump doesn't create
não criado
Uma chave não pode apontar para uma tabela que não existe.
Linha do relatório: foreign_key_skipped
tables on a partition scheme
uma tabela com as linhas de todas as partições
As linhas são as mesmas; particione a tabela de novo no PostgreSQL se precisar.
Linha do relatório: partitions_dropped
temporal tables (SYSTEM_VERSIONING)
duas tabelas: as linhas atuais e o histórico
A tabela e sua tabela de histórico são copiadas como tabelas simples; o PostgreSQL não mantém o histórico sozinho.
Linha do relatório: system_versioning_dropped
NOT NULL columns with values that become NULL
NOT NULL removido
Uma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia.
Linha do relatório: not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functions
listados no relatório
O código deles é escrito em T-SQL, então eles são listados para você recriá-los.
Linha do relatório: not_converted_objects
scripts without CREATE TABLE (data only)
tipos deduzidos dos valores
Um script só de dados tem apenas linhas, então os tipos vêm dos valores.
Linha do relatório: no_schema
expressions in INSERT values
NULL
Um conversor que não executa um banco de dados não consegue avaliá-las.
Linha do relatório: expression_value
types IntoSQL doesn't know
text
O tipo text aceita qualquer valor; mude o tipo depois da carga.
Linha do relatório: unknown_type
dates that aren't valid
NULL
Um valor que não é uma data vira NULL e o relatório o conta.
Linha do relatório: date_out_of_range
NUL characters in text
removido
O texto do PostgreSQL não aceita o caractere NUL. Ele é removido e o relatório conta os valores.
Linha do relatório: nul_removed
text that isn't valid in its encoding
os bytes inválidos como o caractere de substituição
O texto do PostgreSQL deve ser UTF-8 válido.
Linha do relatório: invalid_utf8_replaced
text decoded twice (ñ)
copiado como está
O script contém exatamente esses caracteres, então eles são copiados; o relatório os aponta.
Linha do relatório: mojibake_suspected
| No SQL Server | No PostgreSQL | Linha do relatório |
|---|---|---|
| bit | booleanbit guarda 1 e 0, que são o true e o false do PostgreSQL. | |
| tinyint | smallint com um CHECK de que não é negativoO tinyint do SQL Server vai de 0 a 255; o menor inteiro do PostgreSQL tem sinal, então um CHECK mantém o intervalo. | unsigned_widened |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text | varchar(n) e textO text do PostgreSQL comporta qualquer caractere, então varchar e nvarchar são o mesmo tipo. | |
| decimal(p,s), money, smallmoney | numeric(p,s); money como numeric(19,4)Cada dígito é mantido, e money com suas quatro casas decimais. | |
| datetime, datetime2, smalldatetime | timestamp(p)Um datetime é a leitura de um relógio de parede, como um timestamp sem fuso horário. | |
| datetime2(7), time(7) and datetimeoffset(7) | seis dígitos de segundo, o sétimo cortadoO PostgreSQL guarda microssegundos; o sétimo dígito (100 nanossegundos) é cortado, nunca arredondado, então nenhum valor passa para o segundo ou o dia seguinte. | fraction_cut |
| datetimeoffset | timestamptz, os mesmos instantestimestamptz mantém o instante; o PostgreSQL o mostra no fuso horário da sessão em vez do fuso que cada valor tinha. | |
| time | time(p)Os mesmos horários do dia. | |
| json (SQL Server 2025) | jsonbOs mesmos valores JSON. | |
| uniqueidentifier | uuidOs mesmos identificadores, escritos em minúsculas. | |
| binary, varbinary, image | byteaBytes continuam sendo bytes. | |
| geometry, geography | bytea com os bytes próprios do SQL ServerO SSMS escreve valores espaciais na serialização do SQL Server, que é mantida byte a byte. | spatial_as_native |
| rowversion, timestamp | bytea, sem valoresO SQL Server define a versão de linha sozinho, e o SSMS não escreve valores para ela no script. | rowversion_empty |
| sql_variant, hierarchyid, vector | textO PostgreSQL não tem um tipo equivalente; sql_variant mantém o texto de cada valor e hierarchyid o seu caminho, como /1/2/. xml continua xml. | type_replaced |
| collations that ignore case (_CI_) | comparação exataO PostgreSQL compara texto de forma exata, então colunas que ignoravam maiúsculas no SQL Server agora diferenciam Ana de ana. | case_insensitive_collation |
| IDENTITY | GENERATED BY DEFAULT AS IDENTITY, continuando depois do maior idOs ids copiados carregam como estão, e o contador continua depois do maior deles. | |
| CREATE SEQUENCE | CREATE SEQUENCE com as mesmas opçõesAs sequências do PostgreSQL funcionam do mesmo jeito. O SSMS não escreve até onde uma sequência chegou, então ela começa onde foi criada. | |
| computed columns | colunas geradas, STOREDO PostgreSQL 13 a 17 só armazena colunas geradas; a fórmula é a mesma, com CONCAT escrito para que NULL conte como vazio, como no SQL Server. | virtual_as_stored |
| computed columns with functions PostgreSQL lacks | uma coluna simplesUma fórmula que não pode ser escrita para o PostgreSQL deixa uma coluna simples e uma linha no relatório; o SSMS não escreve valores para colunas computadas. | generated_not_translated |
| defaults with functions PostgreSQL lacks, and NEXT VALUE FOR | sem valor padrãoUm valor padrão que não pode ser escrito para o PostgreSQL fica de fora e é informado no relatório. | default_not_translated |
| CHECK constraints | traduzidosOs mesmos CHECKs, testados à medida que cada linha carrega. | |
| CHECK constraints with functions PostgreSQL lacks | não criadoUm CHECK que não pode ser escrito para o PostgreSQL fica de fora e é informado no relatório. | check_skipped |
| CHECK constraints added WITH NOCHECK or disabled | não criadoO SQL Server não aplica esses CHECKs, então as linhas podem violá-los. | check_not_enforced |
| filtered and columnstore indexes | não criadoO IntoSQL escreve índices b-tree sobre colunas; crie os outros de novo depois da carga. | index_skipped |
| foreign keys | chaves estrangeiras, depois das linhasAs linhas carregam em qualquer ordem, e as chaves as verificam depois. | |
| foreign keys to tables the dump doesn't create | não criadoUma chave não pode apontar para uma tabela que não existe. | foreign_key_skipped |
| tables on a partition scheme | uma tabela com as linhas de todas as partiçõesAs linhas são as mesmas; particione a tabela de novo no PostgreSQL se precisar. | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | duas tabelas: as linhas atuais e o históricoA tabela e sua tabela de histórico são copiadas como tabelas simples; o PostgreSQL não mantém o histórico sozinho. | system_versioning_dropped |
| NOT NULL columns with values that become NULL | NOT NULL removidoUma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia. | not_null_relaxed |
| views, functions, procedures, triggers, synonyms, types and partition functions | listados no relatórioO código deles é escrito em T-SQL, então eles são listados para você recriá-los. | not_converted_objects |
| scripts without CREATE TABLE (data only) | tipos deduzidos dos valoresUm script só de dados tem apenas linhas, então os tipos vêm dos valores. | no_schema |
| expressions in INSERT values | NULLUm conversor que não executa um banco de dados não consegue avaliá-las. | expression_value |
| types IntoSQL doesn't know | textO tipo text aceita qualquer valor; mude o tipo depois da carga. | unknown_type |
| dates that aren't valid | NULLUm valor que não é uma data vira NULL e o relatório o conta. | date_out_of_range |
| NUL characters in text | removidoO texto do PostgreSQL não aceita o caractere NUL. Ele é removido e o relatório conta os valores. | nul_removed |
| text that isn't valid in its encoding | os bytes inválidos como o caractere de substituiçãoO texto do PostgreSQL deve ser UTF-8 válido. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiado como estáO script contém exatamente esses caracteres, então eles são copiados; o relatório os aponta. | mojibake_suspected |
Carregue o script no PostgreSQL
O script cria as tabelas, copia as linhas e depois adiciona chaves, índices e chaves estrangeiras, então carrega rápido e para no primeiro erro.
psql -v ON_ERROR_STOP=1 -d mydb -f sql_server.postgresql.sqlAs chaves estrangeiras são adicionadas como NOT VALID e depois validadas. Se uma linha aponta para uma linha que não existe, o script informa qual restrição, em vez de falhar no meio do caminho.
Para um dump grande, crie o banco de dados antes e execute o script com o psql na mesma máquina do servidor.
O IntoSQL Pro carrega o arquivo direto no PostgreSQL pelo app para desktop ou pela linha de comando, sem escrever um script.
Gere o dump do SQL Server para o melhor resultado
O conversor lê o que o dump contém. Estas opções mantêm mais dos seus dados nele:
- No SSMS, clique com o botão direito no banco de dados, Tasks, Generate Scripts, e escolha as tabelas. dbatools, mssql-scripter e outras ferramentas feitas sobre a mesma biblioteca escrevem o mesmo script.
- Em Advanced, defina Types of data to script como Schema and data. Um script só do schema tem tabelas sem linhas.
- Salve como Unicode, o padrão do SSMS, ou como UTF-8: os dois são lidos do mesmo jeito, e gzip também funciona.
O que não é convertido
Visões, funções, procedimentos, gatilhos, sinônimos, regras e políticas de segurança são escritos em T-SQL. Eles aparecem no relatório pelo nome, nunca são descartados em silêncio, para que você possa reescrevê-los para o PostgreSQL.
Perguntas sobre SQL Server para PostgreSQL
Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato
Meu dump é enviado?
Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.
Qual o tamanho máximo do dump?
O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.
Ele lê o arquivo UTF-16 que o SSMS salva?
Sim. O SSMS salva scripts em UTF-16 por padrão, e o conversor lê UTF-16 e UTF-8 do mesmo jeito, com ou sem gzip, com GO entre os lotes.
De quais versões do SQL Server o script pode vir?
Scripts que o SSMS, o dbatools ou o mssql-scripter escrevem a partir do SQL Server 2017. Cada script de teste vem do SQL Server 2017, 2022 e 2025 e é comparado com a origem célula por célula.
Os valores IDENTITY são mantidos?
Sim. As colunas IDENTITY viram colunas de identidade, cada linha mantém seu id, e o próximo id continua depois do maior. As sequências são criadas com as mesmas opções.
O que acontece com money, datetimeoffset e outros tipos do SQL Server?
bit vira boolean, money numeric(19,4), uniqueidentifier uuid, xml xml, e datetimeoffset timestamptz. datetime2 mantém seis dígitos de segundo, com o sétimo cortado. Colunas que ignoravam maiúsculas comparam de forma exata, e o relatório diz quais.
E os procedimentos, gatilhos e visões?
Eles aparecem no relatório pelo nome e não são convertidos, porque cada banco de dados os escreve na sua própria linguagem.
Em quais versões do PostgreSQL o script carrega?
PostgreSQL 13 a 18. O mesmo script carrega em cada uma delas e para no primeiro erro se algo der errado.