Konwertuj SQL Server do PostgreSQL
Upuść skrypt, który Generate Scripts w SSMS zapisuje ze schematem i danymi, jako .sql lub .sql.gz, w UTF-16 lub UTF-8, i pobierz skrypt PostgreSQL z tymi samymi tabelami, kluczami, indeksami i danymi. Każda wartość, której PostgreSQL nie może przechować bez zmian, i każdy obiekt, którego nie przenosi, są wymienione w raporcie.
18 wierszy przekonwertowanych, 3 poprawki, brak odrzuconych
Tabele w pliku shop_2024_sqlserver.sqlZrzut SQL Server · zapisany przez SQL Server Management Objects · utf-8
orders10 wierszy2
11 kolumn 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 wierszy1
8 kolumn 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
Nieprzekonwertowane
- Widok paid_orders
- Wyzwalacz orders_no_negative
Każda baza danych zapisuje je we własnym języku. Przepisz je dla 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';
Poprawki
- "items" w tabeli orders jest bez znaku, więc ma typ smallint z ograniczeniem CHECK, że nie jest ujemna.
- "shipped_at" w tabeli orders to datetime2(7), z większą liczbą cyfr ułamka sekundy, niż zachowuje PostgreSQL, więc ma typ timestamp(6), a ostatnie cyfry są obcinane.
- "row_version" w tabeli customers to wersja wiersza, którą SQL Server ustawia sam; zrzut nie ma dla niej wartości, więc ma typ bytea i jest pusta.
Do sprawdzenia
- W źródle 6 kolumn tekstowych ignoruje wielkość liter przy porównaniu; PostgreSQL porównuje dokładnie, więc klucze unikalne i wyszukiwanie mogą działać inaczej. Użyj collation lub typu kolumny ignorującego wielkość liter w kolumnach, które tego potrzebują.
- Widoki, wyzwalacze, procedury i zdarzenia nie są konwertowane: 2 obiekty, każdy wymieniony w raporcie. Utwórz je ręcznie w PostgreSQL.
- Ograniczenia CHECK check1 w tabeli orders nie da się zapisać dla PostgreSQL (function isjson), więc go nie utworzono. Zapisz ograniczenie CHECK ręcznie, jeśli jest ważne.
- Indeks idx_orders_pending w tabeli orders używa wyrażenia, którego nie da się zapisać dla PostgreSQL (filtered index), więc go nie utworzono. Utwórz indeks ręcznie, jeśli zapytania go potrzebują.
Plik jest konwertowany na tym komputerze i nigdy nie jest wysyłany.
Inne przykłady:
Co zmienia się między SQL Server a PostgreSQL
Każdy wiersz to reguła stosowana przez konwerter, z wpisem, który dodaje do raportu, gdy reguła coś zmienia w twoich danych.
bit
boolean
bit przechowuje 1 i 0, czyli true i false w PostgreSQL.
tinyint
smallint z CHECK, że wartość nie jest ujemna
tinyint w SQL Server ma zakres od 0 do 255; najmniejsza liczba całkowita w PostgreSQL ma znak, więc ograniczenie CHECK zachowuje ten zakres.
Wpis w raporcie: unsigned_widened
char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text
varchar(n) i text
text w PostgreSQL mieści każdy znak, więc varchar i nvarchar to ten sam typ.
decimal(p,s), money, smallmoney
numeric(p,s); money jako numeric(19,4)
Każda cyfra jest zachowana, money z czterema miejscami po przecinku.
datetime, datetime2, smalldatetime
timestamp(p)
datetime to wskazanie zegara, jak timestamp bez strefy czasowej.
datetime2(7), time(7) and datetimeoffset(7)
sześć cyfr ułamka sekundy, siódma obcięta
PostgreSQL przechowuje mikrosekundy; siódma cyfra (100 nanosekund) jest obcinana, nigdy zaokrąglana, więc żadna wartość nie przechodzi na następną sekundę ani dzień.
Wpis w raporcie: fraction_cut
datetimeoffset
timestamptz, te same momenty
timestamptz zachowuje moment; PostgreSQL pokazuje go w strefie czasowej sesji zamiast przesunięcia, które miała każda wartość.
time
time(p)
Te same godziny dnia.
json (SQL Server 2025)
jsonb
Te same wartości JSON.
uniqueidentifier
uuid
Te same identyfikatory, zapisane małymi literami.
binary, varbinary, image
bytea
Bajty pozostają bajtami.
geometry, geography
bytea z własnymi bajtami SQL Server
SSMS zapisuje wartości przestrzenne w serializacji SQL Server, zachowywanej bajt po bajcie.
Wpis w raporcie: spatial_as_native
rowversion, timestamp
bytea, pusty
SQL Server sam ustawia wersję wiersza, a SSMS nie zapisuje dla niej wartości.
Wpis w raporcie: rowversion_empty
sql_variant, hierarchyid, vector
text
PostgreSQL nie ma odpowiedniego typu; sql_variant zachowuje tekst każdej wartości, a hierarchyid swoją ścieżkę, np. /1/2/. xml zostaje xml.
Wpis w raporcie: type_replaced
collations that ignore case (_CI_)
dokładne porównanie
PostgreSQL porównuje tekst dokładnie, więc kolumny, które w SQL Server ignorowały wielkość liter, teraz odróżniają Ana od ana.
Wpis w raporcie: case_insensitive_collation
IDENTITY
GENERATED BY DEFAULT AS IDENTITY, kontynuowane po najwyższym id
Skopiowane id ładują się bez zmian, a licznik idzie dalej po najwyższym.
CREATE SEQUENCE
CREATE SEQUENCE z tymi samymi opcjami
Sekwencje w PostgreSQL działają tak samo. SSMS nie zapisuje, dokąd doszła sekwencja, więc zaczyna ona od wartości, od której została utworzona.
computed columns
kolumny generowane, STORED
PostgreSQL od 13 do 17 tylko przechowuje kolumny generowane; formuła jest ta sama, z CONCAT zapisanym tak, by NULL liczył się jako pusty, jak w SQL Server.
Wpis w raporcie: virtual_as_stored
computed columns with functions PostgreSQL lacks
zwykła kolumna
Formuła, której nie da się zapisać dla PostgreSQL, zostawia zwykłą kolumnę i wpis w raporcie; SSMS nie zapisuje wartości kolumn obliczanych.
Wpis w raporcie: generated_not_translated
defaults with functions PostgreSQL lacks, and NEXT VALUE FOR
brak wartości domyślnej
Wartość domyślna, której nie da się zapisać dla PostgreSQL, jest pomijana i zgłaszana w raporcie.
Wpis w raporcie: default_not_translated
CHECK constraints
przetłumaczone
Te same ograniczenia CHECK, sprawdzane przy ładowaniu każdego wiersza.
CHECK constraints with functions PostgreSQL lacks
nie jest tworzone
Ograniczenie CHECK, którego nie da się zapisać dla PostgreSQL, jest pomijane i zgłaszane w raporcie.
Wpis w raporcie: check_skipped
CHECK constraints added WITH NOCHECK or disabled
nie jest tworzone
SQL Server nie stosuje tych ograniczeń CHECK, więc wiersze mogą je łamać.
Wpis w raporcie: check_not_enforced
filtered and columnstore indexes
nie jest tworzone
IntoSQL zapisuje indeksy b-tree na kolumnach; pozostałe utwórz ponownie po załadowaniu.
Wpis w raporcie: index_skipped
foreign keys
klucze obce, po wierszach
Wiersze ładują się w dowolnej kolejności, a klucze sprawdzają je potem.
foreign keys to tables the dump doesn't create
nie jest tworzone
Klucz nie może wskazywać tabeli, której nie ma.
Wpis w raporcie: foreign_key_skipped
tables on a partition scheme
jedna tabela z wierszami wszystkich partycji
Wiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w PostgreSQL.
Wpis w raporcie: partitions_dropped
temporal tables (SYSTEM_VERSIONING)
dwie tabele: bieżące wiersze i historia
Tabela i jej tabela historii są kopiowane jako zwykłe tabele; PostgreSQL nie przechowuje historii sam.
Wpis w raporcie: system_versioning_dropped
NOT NULL columns with values that become NULL
NOT NULL usunięte
Kolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało.
Wpis w raporcie: not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functions
wymienione w raporcie
Ich kod jest napisany w T-SQL, więc trafiają na listę do ręcznego odtworzenia.
Wpis w raporcie: not_converted_objects
scripts without CREATE TABLE (data only)
typy odczytane z wartości
Skrypt samych danych zawiera tylko wiersze, więc typy pochodzą z wartości.
Wpis w raporcie: no_schema
expressions in INSERT values
NULL
Konwerter, który nie uruchamia bazy danych, nie może ich obliczyć.
Wpis w raporcie: expression_value
types IntoSQL doesn't know
text
Tekst mieści każdą wartość; zmień typ po załadowaniu.
Wpis w raporcie: unknown_type
dates that aren't valid
NULL
Wartość, która nie jest datą, staje się NULL, a raport ją liczy.
Wpis w raporcie: date_out_of_range
NUL characters in text
usunięte
Tekst w PostgreSQL nie może zawierać znaku NUL. Jest on usuwany, a raport liczy te wartości.
Wpis w raporcie: nul_removed
text that isn't valid in its encoding
błędne bajty jako znak zastępczy
Tekst w PostgreSQL musi być poprawnym UTF-8.
Wpis w raporcie: invalid_utf8_replaced
text decoded twice (ñ)
skopiowane bez zmian
Skrypt zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.
Wpis w raporcie: mojibake_suspected
| W SQL Server | W PostgreSQL | Wpis w raporcie |
|---|---|---|
| bit | booleanbit przechowuje 1 i 0, czyli true i false w PostgreSQL. | |
| tinyint | smallint z CHECK, że wartość nie jest ujemnatinyint w SQL Server ma zakres od 0 do 255; najmniejsza liczba całkowita w PostgreSQL ma znak, więc ograniczenie CHECK zachowuje ten zakres. | unsigned_widened |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text | varchar(n) i texttext w PostgreSQL mieści każdy znak, więc varchar i nvarchar to ten sam typ. | |
| decimal(p,s), money, smallmoney | numeric(p,s); money jako numeric(19,4)Każda cyfra jest zachowana, money z czterema miejscami po przecinku. | |
| datetime, datetime2, smalldatetime | timestamp(p)datetime to wskazanie zegara, jak timestamp bez strefy czasowej. | |
| datetime2(7), time(7) and datetimeoffset(7) | sześć cyfr ułamka sekundy, siódma obciętaPostgreSQL przechowuje mikrosekundy; siódma cyfra (100 nanosekund) jest obcinana, nigdy zaokrąglana, więc żadna wartość nie przechodzi na następną sekundę ani dzień. | fraction_cut |
| datetimeoffset | timestamptz, te same momentytimestamptz zachowuje moment; PostgreSQL pokazuje go w strefie czasowej sesji zamiast przesunięcia, które miała każda wartość. | |
| time | time(p)Te same godziny dnia. | |
| json (SQL Server 2025) | jsonbTe same wartości JSON. | |
| uniqueidentifier | uuidTe same identyfikatory, zapisane małymi literami. | |
| binary, varbinary, image | byteaBajty pozostają bajtami. | |
| geometry, geography | bytea z własnymi bajtami SQL ServerSSMS zapisuje wartości przestrzenne w serializacji SQL Server, zachowywanej bajt po bajcie. | spatial_as_native |
| rowversion, timestamp | bytea, pustySQL Server sam ustawia wersję wiersza, a SSMS nie zapisuje dla niej wartości. | rowversion_empty |
| sql_variant, hierarchyid, vector | textPostgreSQL nie ma odpowiedniego typu; sql_variant zachowuje tekst każdej wartości, a hierarchyid swoją ścieżkę, np. /1/2/. xml zostaje xml. | type_replaced |
| collations that ignore case (_CI_) | dokładne porównaniePostgreSQL porównuje tekst dokładnie, więc kolumny, które w SQL Server ignorowały wielkość liter, teraz odróżniają Ana od ana. | case_insensitive_collation |
| IDENTITY | GENERATED BY DEFAULT AS IDENTITY, kontynuowane po najwyższym idSkopiowane id ładują się bez zmian, a licznik idzie dalej po najwyższym. | |
| CREATE SEQUENCE | CREATE SEQUENCE z tymi samymi opcjamiSekwencje w PostgreSQL działają tak samo. SSMS nie zapisuje, dokąd doszła sekwencja, więc zaczyna ona od wartości, od której została utworzona. | |
| computed columns | kolumny generowane, STOREDPostgreSQL od 13 do 17 tylko przechowuje kolumny generowane; formuła jest ta sama, z CONCAT zapisanym tak, by NULL liczył się jako pusty, jak w SQL Server. | virtual_as_stored |
| computed columns with functions PostgreSQL lacks | zwykła kolumnaFormuła, której nie da się zapisać dla PostgreSQL, zostawia zwykłą kolumnę i wpis w raporcie; SSMS nie zapisuje wartości kolumn obliczanych. | generated_not_translated |
| defaults with functions PostgreSQL lacks, and NEXT VALUE FOR | brak wartości domyślnejWartość domyślna, której nie da się zapisać dla PostgreSQL, jest pomijana i zgłaszana w raporcie. | default_not_translated |
| CHECK constraints | przetłumaczoneTe same ograniczenia CHECK, sprawdzane przy ładowaniu każdego wiersza. | |
| CHECK constraints with functions PostgreSQL lacks | nie jest tworzoneOgraniczenie CHECK, którego nie da się zapisać dla PostgreSQL, jest pomijane i zgłaszane w raporcie. | check_skipped |
| CHECK constraints added WITH NOCHECK or disabled | nie jest tworzoneSQL Server nie stosuje tych ograniczeń CHECK, więc wiersze mogą je łamać. | check_not_enforced |
| filtered and columnstore indexes | nie jest tworzoneIntoSQL zapisuje indeksy b-tree na kolumnach; pozostałe utwórz ponownie po załadowaniu. | index_skipped |
| foreign keys | klucze obce, po wierszachWiersze ładują się w dowolnej kolejności, a klucze sprawdzają je potem. | |
| foreign keys to tables the dump doesn't create | nie jest tworzoneKlucz nie może wskazywać tabeli, której nie ma. | foreign_key_skipped |
| tables on a partition scheme | jedna tabela z wierszami wszystkich partycjiWiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w PostgreSQL. | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | dwie tabele: bieżące wiersze i historiaTabela i jej tabela historii są kopiowane jako zwykłe tabele; PostgreSQL nie przechowuje historii sam. | system_versioning_dropped |
| NOT NULL columns with values that become NULL | NOT NULL usunięteKolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało. | not_null_relaxed |
| views, functions, procedures, triggers, synonyms, types and partition functions | wymienione w raporcieIch kod jest napisany w T-SQL, więc trafiają na listę do ręcznego odtworzenia. | not_converted_objects |
| scripts without CREATE TABLE (data only) | typy odczytane z wartościSkrypt samych danych zawiera tylko wiersze, więc typy pochodzą z wartości. | no_schema |
| expressions in INSERT values | NULLKonwerter, który nie uruchamia bazy danych, nie może ich obliczyć. | expression_value |
| types IntoSQL doesn't know | textTekst mieści każdą wartość; zmień typ po załadowaniu. | unknown_type |
| dates that aren't valid | NULLWartość, która nie jest datą, staje się NULL, a raport ją liczy. | date_out_of_range |
| NUL characters in text | usunięteTekst w PostgreSQL nie może zawierać znaku NUL. Jest on usuwany, a raport liczy te wartości. | nul_removed |
| text that isn't valid in its encoding | błędne bajty jako znak zastępczyTekst w PostgreSQL musi być poprawnym UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | skopiowane bez zmianSkrypt zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje. | mojibake_suspected |
Załaduj skrypt do PostgreSQL
Skrypt tworzy tabele, kopiuje wiersze, a potem dodaje klucze, indeksy i klucze obce, więc ładuje się szybko i zatrzymuje przy pierwszym błędzie.
psql -v ON_ERROR_STOP=1 -d mydb -f sql_server.postgresql.sqlKlucze obce są dodawane jako NOT VALID, a potem sprawdzane. Jeśli wiersz wskazuje na nieistniejący wiersz, skrypt podaje, którego ograniczenia to dotyczy, zamiast przerwać w połowie.
Przy dużym zrzucie najpierw utwórz bazę danych i uruchom skrypt przez psql na tej samej maszynie co serwer.
IntoSQL Pro ładuje plik prosto do PostgreSQL z aplikacji na komputer lub wiersza poleceń, bez pisania skryptu.
Jak zrobić zrzut SQL Server dla najlepszego wyniku
Konwerter odczytuje to, co zawiera zrzut. Te opcje zachowują w nim więcej twoich danych:
- W SSMS kliknij prawym przyciskiem bazę danych, Tasks, Generate Scripts i wybierz tabele. dbatools, mssql-scripter i inne narzędzia oparte na tej samej bibliotece zapisują taki sam skrypt.
- W sekcji Advanced ustaw Types of data to script na Schema and data. Skrypt samego schematu ma tabele bez wierszy.
- Zapisz go jako Unicode, domyślnie w SSMS, lub jako UTF-8: oba są czytane tak samo, a gzip też działa.
Co nie jest konwertowane
Widoki, funkcje, procedury, wyzwalacze, synonimy, reguły i polityki bezpieczeństwa są pisane w T-SQL. Raport wymienia je z nazwy i nigdy nie pomija ich po cichu, więc możesz je przepisać dla PostgreSQL.
Pytania o konwersję SQL Server do PostgreSQL
Nie ma tu odpowiedzi? Napisz do nas przez stronę kontaktu, a odpowie człowiek. Strona kontaktu
Czy mój zrzut jest wysyłany?
Nie. Konwerter działa w przeglądarce i odczytuje zrzut z dysku po kawałku, więc nigdy nie opuszcza on twojego komputera. Aplikacja na komputer i wiersz poleceń też konwertują na twoim komputerze.
Jak duży może być zrzut?
Konwerter nigdy nie trzyma całego zrzutu w pamięci: czyta plik dwa razy, fragmentami, i zapisuje skrypt na bieżąco. Zrzuty wielogigabajtowe konwertują się w przeglądarce, w aplikacji na komputer i w wierszu poleceń.
Czy odczytuje plik UTF-16 zapisany przez SSMS?
Tak. SSMS domyślnie zapisuje skrypty jako UTF-16, a konwerter czyta UTF-16 i UTF-8 tak samo, spakowane gzip lub nie, z GO między partiami.
Z jakich wersji SQL Server może pochodzić skrypt?
Skrypty zapisane przez SSMS, dbatools lub mssql-scripter z SQL Server od wersji 2017. Każdy testowy skrypt pochodzi z SQL Server 2017, 2022 i 2025 i jest porównywany ze źródłem komórka po komórce.
Czy wartości IDENTITY są zachowywane?
Tak. Kolumny IDENTITY stają się kolumnami identity, każdy wiersz zachowuje swoje id, a kolejne id idzie po najwyższym. Sekwencje są tworzone z tymi samymi opcjami.
Co dzieje się z money, datetimeoffset i innymi typami SQL Server?
bit staje się boolean, money numeric(19,4), uniqueidentifier uuid, xml xml, a datetimeoffset timestamptz. datetime2 zachowuje sześć cyfr ułamka sekundy, siódma jest obcinana. Kolumny, które ignorowały wielkość liter, porównują dokładnie, a raport podaje, których to dotyczy.
A procedury, wyzwalacze i widoki?
Raport wymienia je z nazwy, ale nie są konwertowane, bo każda baza danych zapisuje je we własnym języku.
Na jakich wersjach PostgreSQL ładuje się skrypt?
PostgreSQL od 13 do 18. Ten sam skrypt ładuje się na każdej z nich i zatrzymuje przy pierwszym błędzie, jeśli coś pójdzie nie tak.