W MySQL możesz wstawić wiele wierszy w ten sposób:
INSERT INTO 'tablename' ('column1', 'column2') VALUES
('data1', 'data2'),
('data1', 'data2'),
('data1', 'data2'),
('data1', 'data2');
Jednak pojawia się błąd, gdy próbuję zrobić coś takiego. Czy można wstawiać wiele wierszy jednocześnie do bazy danych SQLite? Jaka jest składnia, aby to zrobić?
Odpowiedzi:
aktualizacja
Jak podkreśla BrianCampbell , SQLite 3.7.11 i nowsze obsługują teraz prostszą składnię oryginalnego postu . Jednak pokazane podejście jest nadal odpowiednie, jeśli chcesz uzyskać maksymalną kompatybilność ze starszymi bazami danych.
oryginalna odpowiedź
Gdybym miał uprawnienia, wybiłbym odpowiedź rzeki : możesz wstawić wiele wierszy w SQLite, potrzebujesz tylko innej składni . Aby to doskonale wyjaśnić, przykład OPS MySQL:
Można to przekształcić w SQLite jako:
uwaga na temat wydajności
Pierwotnie użyłem tej techniki do wydajnego ładowania dużych zestawów danych z Ruby on Rails. Jednak , jak zauważa Jaime Cook , nie jest jasne, czy jest to szybsze pakowanie osoby
INSERTs
w ramach jednej transakcji:Jeśli Twoim celem jest wydajność, powinieneś najpierw spróbować.
uwaga na temat UNION vs UNION ALL
Jak skomentowało kilka osób, jeśli użyjesz
UNION ALL
(jak pokazano powyżej), wszystkie wiersze zostaną wstawione, więc w tym przypadku otrzymasz cztery wierszedata1, data2
. Jeśli pominiesz toALL
, zduplikowane wiersze zostaną wyeliminowane (a operacja prawdopodobnie będzie nieco wolniejsza). Używamy UNION ALL, ponieważ bardziej pasuje do semantyki oryginalnego postu.w zamknięciu
PS: Proszę o odpowiedź +1 rzeki , ponieważ najpierw przedstawiła rozwiązanie.
źródło
insert into t values (data),(data),(data)
czybegin transaction; insert into t values (data);insert into t values (data);insert into t values (data);Commit;
?UNION ALL
aby tego uniknąć (lub w przypadku niewielkich przyrostów wydajności).sqlite3.sqlite_version
(powinna to być wersja 3.7.x lub 3.8.x), a niesqlite3.version
(która jest tylko wersją modułu python).Tak, jest to możliwe, ale nie przy zwykłych wartościach wstawianych rozdzielanych przecinkami.
Spróbuj tego...
Tak, jest to trochę brzydkie, ale wystarczająco łatwe, aby zautomatyzować generowanie instrukcji na podstawie zestawu wartości. Wygląda też na to, że musisz tylko zadeklarować nazwy kolumn przy pierwszym wyborze.
źródło
UNION ALL
nie używaćUNION
. Z wyjątkiem sytuacji, gdy chcesz usunąć duplikaty.Tak, od SQLite 3.7.11 jest to obsługiwane w SQLite. Z dokumentacji SQLite :
(kiedy ta odpowiedź została pierwotnie napisana, nie była obsługiwana)
W celu zachowania zgodności ze starszymi wersjami SQLite, można użyć lewę sugerowane przez Andy i fearless_fool użyciu
UNION
, ale do 3.7.11 i później prostsza składnia opisane tutaj powinny być preferowane.źródło
VALUES
.VALUES (...), (...)
) :(VALUES
wskazująca, że można ją powtórzyć, oddzielając ją przecinkami. Połączyłem się z uwagami do wydania dla wersji, dodając funkcję, która mówi „Ulepsz składnię INSERT, aby umożliwić wstawianie wielu wierszy za pomocą klauzuli VALUES”.Napisałem trochę kodu ruby, aby wygenerować pojedynczą 500-elementową wielowierszową wstawkę z serii instrukcji insert, co było znacznie szybsze niż uruchamianie poszczególnych insertów. Potem próbowałem po prostu zawinąć wiele wstawek w jedną transakcję i odkryłem, że mogę uzyskać ten sam rodzaj przyspieszenia przy znacznie mniejszym kodzie.
źródło
Według tej strony nie jest obsługiwane:
Począwszy od wersji 3.7.11 SQLite ma wsparcia wielorzędowe-insert . Richard Hipp komentuje:
źródło
Rozpocznij od wersji 2012-03-20 (3.7.11), sqlite obsługuje następującą składnię INSERT:
Przeczytaj dokumentację: http://www.sqlite.org/lang_insert.html
PS: Proszę +1 do odpowiedzi / odpowiedzi Briana Campbella. nie moje! Najpierw przedstawił rozwiązanie.
źródło
Jak powiedzieli inni plakaty, SQLite nie obsługuje tej składni. Nie wiem, czy złożone INSERT są częścią standardu SQL, ale z mojego doświadczenia wynika, że nie są one implementowane w wielu produktach.
Nawiasem mówiąc, należy pamiętać, że wydajność INSERT w SQLite znacznie się poprawi, jeśli zawrzesz wiele INSERT w jawnej transakcji.
źródło
Tak, sql może to zrobić, ale z inną składnią. Sqlite dokumentacja jest dość dobra, tak przy okazji. Informuje również, że jedynym sposobem wstawienia kilku wierszy jest użycie instrukcji select jako źródła danych do wstawienia.
źródło
Sqlite3 nie może tego zrobić bezpośrednio w SQL, chyba że za pomocą SELECT, i chociaż SELECT może zwrócić „wiersz” wyrażeń, nie wiem, jak sprawić, by zwrócił fałszywą kolumnę.
Jednak CLI może to zrobić:
Jeśli utworzysz pętlę wokół INSERT, zamiast korzystać z
.import
polecenia CLI , postępuj zgodnie ze wskazówkami w sqlite FAQ dla INSERT speed:źródło
.import
polecenia SQLite , jest to po prostu pętla, odczytująca linię z pliku wejściowego (lub tty), a następnie instrukcja INSERT dla tej linii. Niestety nieznacznie poprawiona wydajność.Alex ma rację: instrukcja „wybierz ... związek” utraci kolejność, co jest bardzo ważne dla niektórych użytkowników. Nawet po wstawieniu w określonej kolejności sqlite zmienia rzeczy, więc wolę używać transakcji, jeśli ważna jest kolejność wstawiania.
źródło
nieustraszony_fool ma świetną odpowiedź na starsze wersje. Chciałem tylko dodać, że musisz się upewnić, że masz wszystkie kolumny na liście. Więc jeśli masz 3 kolumny, musisz upewnić się, że wybierz działa na 3 kolumny.
Przykład: Mam 3 kolumny, ale chcę wstawić tylko dane o wartości 2 kolumn. Załóżmy, że nie obchodzi mnie pierwsza kolumna, ponieważ jest to standardowy identyfikator liczby całkowitej. Mógłbym zrobić następujące ...
Uwaga: Pamiętaj, że instrukcja „wybierz ... związek” utraci zamówienie. (Od OS1)
źródło
źródło
Nie możesz, ale nie sądzę, żebyś za niczym tęsknił.
Ponieważ zawsze wywołujesz sqlite, prawie nie ma znaczenia, czy wykonasz 1 instrukcję insert, czy 100 instrukcji insert. Zatwierdzenie zajmuje jednak dużo czasu, więc umieść te 100 wstawek w transakcji.
Sqlite jest znacznie szybszy, gdy używasz sparametryzowanych zapytań (potrzeba znacznie mniej analizy), więc nie łączę dużych instrukcji takich jak to:
Muszą być analizowane raz po raz, ponieważ każde zestawione zdanie jest inne.
źródło
w mysql lite nie można wstawiać wielu wartości, ale można zaoszczędzić czas, otwierając połączenie tylko raz, a następnie wykonując wszystkie wstawienia, a następnie zamykając połączenie. Oszczędza dużo czasu
źródło
Problem z korzystaniem z transakcji polega na tym, że blokujesz tabelę również do odczytu. Więc jeśli masz naprawdę dużo danych do wstawienia i potrzebujesz dostępu do swoich danych, na przykład podglądu, ten sposób nie działa dobrze.
Problem z innym rozwiązaniem polega na tym, że tracisz kolejność wstawiania
W sqlite dane będą przechowywane a, b, c, d ...
źródło
Używam 3.6.13
Polecam w ten sposób:
Po wstawieniu 50 rekordów na raz zajmuje to tylko sekundę lub krócej.
To prawda, że użycie sqlite do wstawiania wielu wierszy jednocześnie jest bardzo możliwe. Przez @Andy napisał.
dzięki Andy +1
źródło
źródło
Jeśli używasz wtyczki firefox menedżera Sqlite , obsługuje ona wstawianie zbiorcze zINSERT
instrukcji SQL.W rzeczywistości nie obsługuje tego, ale przeglądarka Sqlite działa (działa w systemie Windows, OS X, Linux)
źródło
Mam zapytanie jak poniżej, ale ze sterownikiem ODBC SQLite ma błąd z „”, mówi. Uruchamiam vbscript w HTA (aplikacja HTML).
źródło
Na sqlite 3.7.2:
i tak dalej
źródło
Jestem w stanie uczynić zapytanie dynamicznym. To jest mój stół:
CREATE TABLE "tblPlanner" ("probid" text,"userid" TEXT,"selectedtime" DATETIME,"plannerid" TEXT,"isLocal" BOOL,"applicationid" TEXT, "comment" TEXT, "subject" TEXT)
i otrzymuję wszystkie dane przez
JSON
, więc po przejściu wszystkiego do środka postępowałemNSArray
następująco:I na koniec zapytanie wyjściowe jest następujące:
który działa również dobrze przez kod i jestem w stanie pomyślnie zapisać wszystko w SQLite.
Wcześniej sprawiłem, że
UNION
zapytania były dynamiczne, ale zaczęło to dawać jakiś błąd składniowy. W każdym razie działa to dobrze dla mnie.źródło
Dziwi mnie, że nikt nie wspomniał o przygotowanych oświadczeniach . O ile nie używasz SQL samodzielnie, a nie w żadnym innym języku, pomyślałem, że przygotowane instrukcje zawinięte w transakcję byłyby najbardziej efektywnym sposobem wstawiania wielu wierszy.
źródło
możesz użyć InsertHelper, jest to łatwe i szybkie
dokumentacja: http://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html
instruktaż: http://www.outofwhatbox.com/blog/2010/12/android-using-databaseutils-inserthelper-for-faster-insertions-into-sqlite-database/
Edycja: InsertHelper jest przestarzałe od poziomu API 17
źródło
Jeśli używasz powłoki bash, możesz użyć tego:
Lub jeśli korzystasz z sqlite CLI, musisz to zrobić:
Jak to działa? Wykorzystuje to, jeśli tabela
tab
:następnie
select a.id, b.id from tab a, tab b
wracai tak dalej. Po pierwszym wykonaniu wstawiamy 2 wiersze, a następnie 2 ^ 3 = 8. (trzy, ponieważ mamy
tab a, tab b, tab c
)Po drugim wykonaniu wstawiamy dodatkowe
(2+8)^3=1000
wierszeNastępnie wstawiamy
max(1000^3, 5e5)=500000
wiersze i tak dalej ...Jest to najszybsza znana mi metoda zapełniania bazy danych SQLite.
źródło