Kopiowanie danych z jednej bazy danych SQLite do innej

141

Mam 2 bazy danych SQLite ze wspólnymi danymi, ale o różnych celach i chciałem uniknąć ponownego wprowadzania danych, więc zastanawiałem się, czy można skopiować całą tabelę z jednej bazy danych do drugiej?

Leonardo Marques
źródło

Odpowiedzi:

171

Będziesz musiał dołączyć bazę danych X do bazy danych Y za pomocą polecenia ATTACH , a następnie uruchomić odpowiednie polecenia Wstaw do tabel, które chcesz przenieść.

INSERT INTO X.TABLE SELECT * FROM Y.TABLE;

Lub, jeśli kolumny nie są dopasowane w kolejności:

INSERT INTO X.TABLE(fieldname1, fieldname2) SELECT fieldname1, fieldname2 FROM Y.TABLE;
Michael D. Irizarry
źródło
1
Również jeśli jest używany program SQLite Expert Personal, daje on szansę na kliknięcie prawym przyciskiem myszy i DOŁĄCZENIE baz danych
mehmet,
6
Najpierw musisz utworzyć tabelę!
Cris Luengo
55

Rozważmy przykład, w którym mam dwie bazy danych, a mianowicie allmsa.db i atlanta.db. Powiedzmy, że baza danych allmsa.db zawiera tabele dla wszystkich msas w USA, a baza danych atlanta.db jest pusta.

Naszym celem jest skopiowanie tabeli atlanta z pliku allmsa.db do atlanta.db.

Kroki

  1. sqlite3 atlanta.db (aby przejść do bazy danych atlanta)
  2. Dołącz allmsa.db. Można to zrobić za pomocą polecenia, ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; zwróć uwagę, że podajemy całą ścieżkę do bazy danych do dołączenia.
  3. sprawdź listę baz danych za pomocą sqlite> .databases możesz zobaczyć dane wyjściowe jako
seq nazwa pliku                                                      
--- --------------- -------------------------------- --------------------------
0 main /mnt/fastaccessDS/core/csv/atlanta.db                  
02:00 /mnt/fastaccessDS/core/csv/allmsa.db 
  1. teraz dochodzisz do swojego rzeczywistego celu. Użyj polecenia INSERT INTO atlanta SELECT * FROM AM.atlanta;

To powinno służyć twojemu celowi.

Neeraj Chandak
źródło
2
Korzystanie z funkcji „INSERT INTO atlanta SELECT * FROM AM.atlanta;” schrzanił rzeczy. Skopiował wszystkie dane, ale niektóre pola zostały zamienione! Nie używaj tego. Zamiast tego użyj polecenia z zaakceptowanej odpowiedzi lub nawet bardziej wyraźnie: „WSTAWIĆ DO X.TABLE (Id, wartość) SELECT Id, Value FROM Y.TABLE; To zadziałało dobrze dla mnie.
Karim Sonbol
@KarimSonbol Jedyna różnica polega na tym, że w przypadku zaakceptowanej odpowiedzi transfer odbywa się Z bazy danych, w której się znajdujesz, DO dołączonej bazy danych, podczas gdy w tej odpowiedzi jest odwrotnie.
Tulains Córdova
@ TulainsCórdova: Zaakceptowana odpowiedź (ostatni wariant) oznacza, że ​​jest inna, ponieważ działa nawet wtedy, gdy „kolumny nie są dopasowane w kolejności”. Mówisz, że to nieprawda?
LarsH
52

Najłatwiejszy i poprawny sposób na jednej linii:

sqlite3 old.db ".dump mytable" | sqlite3 new.db

Klucz podstawowy i typy kolumn zostaną zachowane.

Bernardo Ramos
źródło
1
To trochę oczywiste ... ale jeśli w docelowej bazie danych istnieje już tabela o tej nazwie, nie jest to możliwe. Nie można więc dodawać do już istniejących danych za pomocą tego rozwiązania (w przeciwnym razie świetnie)
Martin Meeser
@MartinMeeser Pytanie dotyczy kopiowania tabeli, a nie łączenia tabel. Możesz spróbować scalić, zrzucając do pliku tymczasowego, edytując plik, usuwając instrukcję CREATE TABLE i używając pliku tymczasowego jako danych wejściowych dla new.db. Ale konflikty na kluczu głównym mogą się zdarzyć
Bernardo Ramos
@MartinMeeser, faktycznie scalanie działa, jeśli tabela istnieje w docelowej bazie danych, otrzymasz komunikat o błędzie, ale dane zostaną skopiowane.
Vincnetas
3
@MartinMeeser w zainstalowanej przeze mnie wersji oprogramowania SQLite (v3.19.3) .dumptworzy polecenie CREATE TABLE IF NOT EXISTS ...i nie ma błędu, mimo że istnieje moja tabela docelowa.
Reversed Engineer
1
Prosty, przyjazny dla systemu UNIX sposób rozwiązania problemu. Zasługujesz na moje uznanie. Dziękuję Ci!
Augusto Destrero
10

Do jednorazowej akcji możesz użyć .dump i .read.

Zrzuć tabelę my_table z pliku old_db.sqlite

c:\sqlite>sqlite3.exe old_db.sqlite
sqlite> .output mytable_dump.sql
sqlite> .dump my_table
sqlite> .quit

Przeczytaj zrzut do pliku new_db.sqlite, zakładając, że tabela tam nie istnieje

c:\sqlite>sqlite3.exe new_db.sqlite
sqlite> .read mytable_dump.sql

Teraz sklonowałeś swój stół. Aby to zrobić dla całej bazy danych, po prostu pomiń nazwę tabeli w poleceniu .dump.

Bonus: bazy danych mogą mieć różne kodowania.

Thinkeye
źródło
7

Kod celu C do kopiowania tabeli z bazy danych do innej bazy danych

-(void) createCopyDatabase{

          NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
          NSString *documentsDir = [paths objectAtIndex:0];

          NSString *maindbPath = [documentsDir stringByAppendingPathComponent:@"User.sqlite"];;

          NSString *newdbPath = [documentsDir stringByAppendingPathComponent:@"User_copy.sqlite"];
          NSFileManager *fileManager = [NSFileManager defaultManager];
          char *error;

         if ([fileManager fileExistsAtPath:newdbPath]) {
             [fileManager removeItemAtPath:newdbPath error:nil];
         }
         sqlite3 *database;
         //open database
        if (sqlite3_open([newdbPath UTF8String], &database)!=SQLITE_OK) {
            NSLog(@"Error to open database");
        }

        NSString *attachQuery = [NSString stringWithFormat:@"ATTACH DATABASE \"%@\" AS aDB",maindbPath];

       sqlite3_exec(database, [attachQuery UTF8String], NULL, NULL, &error);
       if (error) {
           NSLog(@"Error to Attach = %s",error);
       }

       //Query for copy Table
       NSString *sqlString = @"CREATE TABLE Info AS SELECT * FROM aDB.Info";
       sqlite3_exec(database, [sqlString UTF8String], NULL, NULL, &error);
        if (error) {
            NSLog(@"Error to copy database = %s",error);
        }

        //Query for copy Table with Where Clause

        sqlString = @"CREATE TABLE comments AS SELECT * FROM aDB.comments Where user_name = 'XYZ'";
        sqlite3_exec(database, [sqlString UTF8String], NULL, NULL, &error);
        if (error) {
            NSLog(@"Error to copy database = %s",error);
        }
 }
avinash
źródło
0

Musiałem przenieść dane z kompaktowej bazy danych serwera sql do sqlite, więc używając sql server 2008 możesz kliknąć prawym przyciskiem myszy na tabelę i wybrać „Script Table To”, a następnie „Data to Inserts”. Skopiuj instrukcje wstawiania, aby usunąć instrukcje „GO” i zostało wykonane pomyślnie po zastosowaniu do bazy danych sqlite przy użyciu aplikacji „DB Browser for Sqlite”.

Michael Gabay
źródło
0

Pierwszy scenariusz: DB1.sqlite i DB2.sqlite mają tę samą tabelę (t1), ale DB1 jest bardziej „aktualny” niż DB2. Jeśli jest mały, usuń tabelę z bazy danych DB2 i utwórz ją ponownie z danymi:

> DROP TABLE IF EXISTS db2.t1; CREATE TABLE db2.t1 AS SELECT * FROM db1.t1;

Drugi scenariusz: jeśli jest to duży stół, lepiej będzie, jeśli INSERT if not existszastosujesz rozwiązanie typu. Jeśli masz Unique Keykolumnę, jest to prostsze, w przeciwnym razie musiałbyś użyć kombinacji pól (być może każdego pola), a w pewnym momencie nadal jest szybsze dropponowne createustawienie tabeli; jest to zawsze prostsze (wymaga mniej myślenia).


KONFIGURACJA: otwórz SQLite bez bazy danych, która tworzy bazę danych temporaryw pamięci main, a następnie attachDB1.sqlite i DB2.sqlite

> sqlite3
sqlite> ATTACH "DB1.sqlite" AS db1
sqlite> ATTACH "DB2.sqlite" AS db2

i użyj, .databasesaby zobaczyć załączone bazy danych i ich pliki.

sqlite> .databases
main: 
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite
Sprawny Mac
źródło
UWAGA: To nie jest zachowanie UNIQUEi PRIMARY KEYcechy, więc jeśli masz te, to albo trzeba DROP TABLEi ręcznie CREATEi INSERTczy używać .dumpi .read metody wymienione powyżej przez @Thinkeye.
Able Mac