Konwertuj SQL Server do SQLite
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 SQLite z tymi samymi tabelami, kluczami, indeksami i danymi. Każda wartość, której SQLite 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 TEXT not null items INTEGER not null ordered_at DATETIME not null shipped_at DATETIME note TEXT details TEXT order_ref TEXT not null total_with_tax DECIMAL(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 INTEGER not null signed_up DATE created_at TIMESTAMP not null row_version BLOB
Nieprzekonwertowane
- Widok paid_orders
- Wyzwalacz orders_no_negative
Każda baza danych zapisuje je we własnym języku. Przepisz je dla SQLite.
-- Written by IntoSQL from a SQL Server dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL,
status VARCHAR(10) DEFAULT 'pending' NOT NULL,
total TEXT NOT NULL,
items INTEGER DEFAULT 1 NOT NULL,
ordered_at DATETIME NOT NULL,
shipped_at DATETIME,
note TEXT,
details TEXT,
order_ref TEXT NOT NULL,
total_with_tax DECIMAL(12,2) GENERATED ALWAYS AS (CAST(total * (1.16) AS NUMERIC)) 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)),
CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id)
);
CREATE TABLE customers ( -- People who bought at least once
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL,
country VARCHAR(2) DEFAULT 'US' NOT NULL,
is_active INTEGER DEFAULT 1 NOT NULL,
signed_up DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
row_version BLOB,
CONSTRAINT customers_is_active_check CHECK (is_active IN (0, 1))
);
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12.0000000');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(1,1,'shipped','129.9000',3,'2024-03-01T10:00:00.0000000','2024-03-02T16:30:00.1234567',NULL,'{"gift": false}','0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(2,2,'paid','54.0000',1,'2024-03-02T11:15:00.0000000',NULL,'Gift wrap 🎁','{"gift": true, "wrap": "red"}','1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(3,1,'cancelled','12.5000',1,'2024-03-03T09:45:00.0000000',NULL,'Customer changed their mind',NULL,'2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(4,4,'shipped','980.0000',12,'2024-03-05T02:10:00.0000000','2024-03-07T08:00:00.0000000','请小心轻放','{"fragile": true}','3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(5,5,'pending','45.7500',2,'2024-03-08T17:20:00.0000000',NULL,'Leave at the door; ring twice',NULL,'4f1e806c-7d5b-4c2e-9a99-5e6f708192a3');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(6,6,'shipped','310.4000',5,'2024-03-10T13:00:00.0000000','2024-03-11T09:00:00.0000000','Fragile: "glass"','{"fragile": true}','50f2917d-8e6c-4d3f-8baa-6f708192a3b4');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(7,8,'paid','76.2000',2,'2024-03-11T18:45:00.0000000',NULL,NULL,NULL,'6103a28e-9f7d-4e40-9cbb-708192a3b4c5');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(8,2,'shipped','19.9900',1,'2024-03-12T08:00:00.0000000','9999-12-31T23:59:59.9999999','Shipped date set to the maximum by an old import',NULL,'7214b39f-a08e-4f51-8dcc-8192a3b4c5d6');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(9,3,'shipped','64.0000',2,'2024-03-14T15:30:00.0000000','2024-03-15T10:00:00.0000000','Two parcels','{"parcels": [1, 2]}','8325c4a0-b19f-4062-9edd-92a3b4c5d6e7');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(10,7,'paid','1499.0000',1,'2024-03-15T21:05:00.0000000',NULL,'C:\Users\ravi\invoice.pdf',NULL,'9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8');
-- Indexes, triggers and counters, after the rows so each index builds once.
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_email ON customers (email);
UPDATE sqlite_sequence SET seq = max(seq, 0) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 0 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
UPDATE sqlite_sequence SET seq = max(seq, 0) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 0 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
COMMIT;
-- Rows whose foreign key finds no parent, if any: the load doesn't stop for them.
PRAGMA foreign_key_check;
Poprawki
- "items" w tabeli orders jest bez znaku, więc ma typ INTEGER z ograniczeniem CHECK, że nie jest ujemna.
- "total" w tabeli orders to money, więcej cyfr, niż mieści liczba w SQLite, więc jest tekstem ze wszystkimi cyframi.
- "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 BLOB i jest pusta.
Do sprawdzenia
- W źródle 6 kolumn tekstowych ignoruje wielkość liter przy porównaniu; SQLite 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 SQLite.
- Ograniczenia CHECK check1 w tabeli orders nie da się zapisać dla SQLite (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 SQLite (filtered index), więc go nie utworzono. Utwórz indeks ręcznie, jeśli zapytania go potrzebują.
- Wartości domyślnej "order_ref" w tabeli orders nie da się zapisać dla SQLite (function uuid), więc kolumna nie ma wartości domyślnej. Dodaj wartość domyślną ręcznie, jeśli nowe wiersze jej potrzebują.
Plik jest konwertowany na tym komputerze i nigdy nie jest wysyłany.
Inne przykłady:
Co zmienia się między SQL Server a SQLite
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
INTEGER 0 lub 1 z CHECK
SQLite nie ma typu logicznego; jego własne true i false to 1 i 0.
tinyint
INTEGER z CHECK, że wartość nie jest ujemna
tinyint w SQL Server ma zakres od 0 do 255; 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, bez wymuszania
SQLite zachowuje zadeklarowany typ dla narzędzi, ale nie ogranicza długości.
decimal(p,s) past 15 digits, money
TEXT
SQLite przechowuje w liczbie około 15 cyfr znaczących. Szersze liczby są zapisywane jako tekst, aby każda cyfra pozostała dokładna.
Wpis w raporcie: decimal_as_text
date, datetime, datetime2, smalldatetime
DATETIME jako tekst ISO 8601, ze wszystkimi cyframi
SQLite przechowuje daty jako tekst, który czytają jego funkcje dat.
datetimeoffset
TIMESTAMP jako tekst ISO 8601 w UTC
SQLite nie ma typu, który zachowuje przesunięcie, więc każdy moment jest zapisywany w UTC: ten sam moment niezależnie od przesunięcia.
Wpis w raporcie: moments_as_utc
time
TIME jako tekst
SQLite przechowuje godziny jako tekst, ze wszystkimi cyframi.
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
json (SQL Server 2025)
TEXT
Te same wartości JSON, które odczytują funkcje JSON w SQLite.
uniqueidentifier
TEXT
Te same identyfikatory, zapisane małymi literami.
binary, varbinary, image
BLOB
Bajty pozostają bajtami.
geometry, geography
BLOB 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
BLOB, pusty
SQL Server sam ustawia wersję wiersza, a SSMS nie zapisuje dla niej wartości.
Wpis w raporcie: rowversion_empty
xml, sql_variant, hierarchyid, vector
TEXT
SQLite nie ma odpowiedniego typu; xml i sql_variant zachowują tekst każdej wartości, a hierarchyid swoją ścieżkę, np. /1/2/.
Wpis w raporcie: type_replaced
collations that ignore case (_CI_)
dokładne porównanie
SQLite porównuje tekst dokładnie, chyba że ustawisz inaczej, a jego NOCASE ujednolica tylko litery ASCII.
Wpis w raporcie: case_insensitive_collation
IDENTITY
INTEGER PRIMARY KEY AUTOINCREMENT, kontynuowane po najwyższym id
SQLite liczy klucz główny będący jedną liczbą całkowitą, a AUTOINCREMENT nie pozwala ponownie użyć id.
IDENTITY columns that aren't the whole primary key
INTEGER bez licznika
SQLite liczy tylko kolumnę, która jest całym kluczem głównym, więc kolumna zachowuje swoje wartości, a nowe wiersze potrzebują własnych.
Wpis w raporcie: counter_dropped
CREATE SEQUENCE
nie jest tworzone
SQLite nie ma sekwencji. Wartości wydane przez sekwencję są w wierszach.
Wpis w raporcie: sequence_not_converted
computed columns
GENERATED ALWAYS AS, STORED przy PERSISTED, w przeciwnym razie VIRTUAL
SQLite 3.31 i nowsze obliczają je na te same dwa sposoby, z CONCAT zapisanym tak, by NULL liczył się jako pusty, jak w SQL Server.
computed columns with functions SQLite lacks
zwykła kolumna
Formuła, której nie da się zapisać, zostawia zwykłą kolumnę i wpis w raporcie; SSMS nie zapisuje wartości kolumn obliczanych.
Wpis w raporcie: generated_not_translated
defaults with functions SQLite lacks, and NEXT VALUE FOR
brak wartości domyślnej
Wartość domyślna, której nie da się zapisać, 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 SQLite lacks
nie jest tworzone
Ograniczenie CHECK, którego nie da się zapisać, 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 całych kolumnach; pozostałe utwórz ponownie po załadowaniu.
Wpis w raporcie: index_skipped
foreign keys
w CREATE TABLE, ładowane bez sprawdzania, potem wypisywane przez PRAGMA foreign_key_check
SQLite przyjmuje klucze obce tylko w CREATE TABLE i sprawdza je tylko z włączonym PRAGMA foreign_keys. Wiersze ładują się bez sprawdzania, a na końcu skrypt wypisuje każdy wiersz bez rodzica.
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 SQLite.
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; SQLite nie przechowuje historii sam.
Wpis w raporcie: system_versioning_dropped
schemas
jeden plik, nazwa każdej tabeli zaczyna się od nazwy jej schematu
Plik SQLite to jedna baza danych, więc nazwa schematu rozróżnia tabele o tej samej nazwie; tabele z dbo zachowują nazwy.
Wpis w raporcie: schemas_merged
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
NUL characters in text
zachowane
Tekst w SQLite może zawierać znak NUL, więc wartość jest kopiowana bez zmian.
text that isn't valid in its encoding
błędne bajty jako znak zastępczy
Skrypt jest w UTF-8 i każda wartość musi być poprawnym tekstem.
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 SQLite | Wpis w raporcie |
|---|---|---|
| bit | INTEGER 0 lub 1 z CHECKSQLite nie ma typu logicznego; jego własne true i false to 1 i 0. | |
| tinyint | INTEGER z CHECK, że wartość nie jest ujemnatinyint w SQL Server ma zakres od 0 do 255; ograniczenie CHECK zachowuje ten zakres. | unsigned_widened |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text | VARCHAR(n) i TEXT, bez wymuszaniaSQLite zachowuje zadeklarowany typ dla narzędzi, ale nie ogranicza długości. | |
| decimal(p,s) past 15 digits, money | TEXTSQLite przechowuje w liczbie około 15 cyfr znaczących. Szersze liczby są zapisywane jako tekst, aby każda cyfra pozostała dokładna. | decimal_as_text |
| date, datetime, datetime2, smalldatetime | DATETIME jako tekst ISO 8601, ze wszystkimi cyframiSQLite przechowuje daty jako tekst, który czytają jego funkcje dat. | |
| datetimeoffset | TIMESTAMP jako tekst ISO 8601 w UTCSQLite nie ma typu, który zachowuje przesunięcie, więc każdy moment jest zapisywany w UTC: ten sam moment niezależnie od przesunięcia. | moments_as_utc |
| time | TIME jako tekstSQLite przechowuje godziny jako tekst, ze wszystkimi cyframi. | |
| dates that aren't valid | NULLWartość, która nie jest datą, staje się NULL, a raport ją liczy. | date_out_of_range |
| json (SQL Server 2025) | TEXTTe same wartości JSON, które odczytują funkcje JSON w SQLite. | |
| uniqueidentifier | TEXTTe same identyfikatory, zapisane małymi literami. | |
| binary, varbinary, image | BLOBBajty pozostają bajtami. | |
| geometry, geography | BLOB z własnymi bajtami SQL ServerSSMS zapisuje wartości przestrzenne w serializacji SQL Server, zachowywanej bajt po bajcie. | spatial_as_native |
| rowversion, timestamp | BLOB, pustySQL Server sam ustawia wersję wiersza, a SSMS nie zapisuje dla niej wartości. | rowversion_empty |
| xml, sql_variant, hierarchyid, vector | TEXTSQLite nie ma odpowiedniego typu; xml i sql_variant zachowują tekst każdej wartości, a hierarchyid swoją ścieżkę, np. /1/2/. | type_replaced |
| collations that ignore case (_CI_) | dokładne porównanieSQLite porównuje tekst dokładnie, chyba że ustawisz inaczej, a jego NOCASE ujednolica tylko litery ASCII. | case_insensitive_collation |
| IDENTITY | INTEGER PRIMARY KEY AUTOINCREMENT, kontynuowane po najwyższym idSQLite liczy klucz główny będący jedną liczbą całkowitą, a AUTOINCREMENT nie pozwala ponownie użyć id. | |
| IDENTITY columns that aren't the whole primary key | INTEGER bez licznikaSQLite liczy tylko kolumnę, która jest całym kluczem głównym, więc kolumna zachowuje swoje wartości, a nowe wiersze potrzebują własnych. | counter_dropped |
| CREATE SEQUENCE | nie jest tworzoneSQLite nie ma sekwencji. Wartości wydane przez sekwencję są w wierszach. | sequence_not_converted |
| computed columns | GENERATED ALWAYS AS, STORED przy PERSISTED, w przeciwnym razie VIRTUALSQLite 3.31 i nowsze obliczają je na te same dwa sposoby, z CONCAT zapisanym tak, by NULL liczył się jako pusty, jak w SQL Server. | |
| computed columns with functions SQLite lacks | zwykła kolumnaFormuła, której nie da się zapisać, zostawia zwykłą kolumnę i wpis w raporcie; SSMS nie zapisuje wartości kolumn obliczanych. | generated_not_translated |
| defaults with functions SQLite lacks, and NEXT VALUE FOR | brak wartości domyślnejWartość domyślna, której nie da się zapisać, 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 SQLite lacks | nie jest tworzoneOgraniczenie CHECK, którego nie da się zapisać, 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 całych kolumnach; pozostałe utwórz ponownie po załadowaniu. | index_skipped |
| foreign keys | w CREATE TABLE, ładowane bez sprawdzania, potem wypisywane przez PRAGMA foreign_key_checkSQLite przyjmuje klucze obce tylko w CREATE TABLE i sprawdza je tylko z włączonym PRAGMA foreign_keys. Wiersze ładują się bez sprawdzania, a na końcu skrypt wypisuje każdy wiersz bez rodzica. | |
| 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 SQLite. | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | dwie tabele: bieżące wiersze i historiaTabela i jej tabela historii są kopiowane jako zwykłe tabele; SQLite nie przechowuje historii sam. | system_versioning_dropped |
| schemas | jeden plik, nazwa każdej tabeli zaczyna się od nazwy jej schematuPlik SQLite to jedna baza danych, więc nazwa schematu rozróżnia tabele o tej samej nazwie; tabele z dbo zachowują nazwy. | schemas_merged |
| 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 |
| NUL characters in text | zachowaneTekst w SQLite może zawierać znak NUL, więc wartość jest kopiowana bez zmian. | |
| text that isn't valid in its encoding | błędne bajty jako znak zastępczySkrypt jest w UTF-8 i każda wartość musi być poprawnym tekstem. | 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 SQLite
Skrypt tworzy tabele, kopiuje wiersze, a potem dodaje klucze, indeksy i klucze obce, więc ładuje się szybko i zatrzymuje przy pierwszym błędzie.
sqlite3 -bail mydb.sqlite < sql_server.sqlite.sqlKlucze obce są deklarowane w każdej tabeli, a wiersze ładują się z wyłączonym sprawdzaniem kluczy obcych. Potem skrypt wypisuje każdy wiersz, który wskazuje na nieistniejący wiersz, zamiast przerwać w połowie.
Duży zrzut ładuj do nowego pliku na dysku lokalnym. Skrypt ładuje wszystko w jednej transakcji z wyłączoną synchronizacją, więc działa z szybkością dysku, a przerwane ładowanie nie zostawia niepełnych tabel.
Wiersz poleceń ładuje plik prosto do bazy SQLite, bez pisania skryptu. To nic nie kosztuje.
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 SQLite.
Pytania o konwersję SQL Server do SQLite
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?
Kolumna IDENTITY, która stanowi cały klucz główny tabeli, staje się INTEGER PRIMARY KEY AUTOINCREMENT, każdy wiersz zachowuje swoje id, a kolejne id idzie po najwyższym. Każda inna zachowuje wartości bez licznika.
Co dzieje się z money, datetimeoffset i innymi typami SQL Server?
bit staje się 0 i 1, datetime2 tekstem ISO 8601 ze wszystkimi cyframi, datetimeoffset tekstem w UTC, a szerokie liczby decimal i money dokładnym tekstem. Kolumny obliczane pozostają obliczane. Schematy stają się prefiksami nazw tabel.
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 SQLite ładuje się skrypt?
SQLite 3.31 i nowsze. Każdy testowy skrypt ładuje się na 3.31 i 3.54 i zatrzymuje przy pierwszym błędzie, jeśli coś pójdzie nie tak.