Kopieren von Daten von einer SQLite-Datenbank in eine andere

141

Ich habe 2 SQLite-Datenbanken mit gemeinsamen Daten, aber unterschiedlichen Zwecken, und ich wollte vermeiden, Daten erneut einzufügen. Ich habe mich gefragt, ob es möglich ist, eine ganze Tabelle von einer Datenbank in eine andere zu kopieren.

Leonardo Marques
quelle

Antworten:

170

Sie müssen Datenbank X mit Datenbank Y mit dem Befehl ATTACH verknüpfen und dann die entsprechenden Befehle zum Einfügen in die Tabellen ausführen, die Sie übertragen möchten.

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

Oder wenn die Spalten nicht in der richtigen Reihenfolge übereinstimmen:

INSERT INTO X.TABLE(fieldname1, fieldname2) SELECT fieldname1, fieldname2 FROM Y.TABLE;
Michael D. Irizarry
quelle
1
Auch wenn das SQLite Expert Personal-Programm verwendet wird, besteht die Möglichkeit, mit der rechten Maustaste zu klicken und Datenbanken
anzuhängen
6
Sie müssen zuerst die Tabelle erstellen!
Cris Luengo
55

Stellen Sie sich ein Beispiel vor, in dem ich zwei Datenbanken habe, nämlich allmsa.db und atlanta.db. Angenommen, die Datenbank allmsa.db enthält Tabellen für alle msas in den USA und die Datenbank atlanta.db ist leer.

Unser Ziel ist es, die Tabelle atlanta von allmsa.db nach atlanta.db zu kopieren.

Schritte

  1. sqlite3 atlanta.db (um in die atlanta Datenbank zu gelangen)
  2. Fügen Sie allmsa.db hinzu. Dies kann mit der Befehlsnotiz erfolgen ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; , dass wir den gesamten Pfad der anzuhängenden Datenbank angeben.
  3. Überprüfen Sie die Datenbankliste, indem sqlite> .databases Sie die Ausgabe als sehen
seq name file                                                      
--- --------------- -------------------------------- --------------------------
0 main /mnt/fastaccessDS/core/csv/atlanta.db                  
2 Uhr morgens /mnt/fastaccessDS/core/csv/allmsa.db 
  1. Jetzt kommst du zu deinem eigentlichen Ziel. Verwenden Sie den Befehl INSERT INTO atlanta SELECT * FROM AM.atlanta;

Dies sollte Ihren Zweck erfüllen.

Neeraj Chandak
quelle
2
Verwenden von 'INSERT INTO atlanta SELECT * FROM AM.atlanta;' Dinge durcheinander gebracht. Es wurden alle Daten kopiert, aber einige Felder wurden ausgetauscht! Benutze es nicht. Verwenden Sie stattdessen den Befehl aus der akzeptierten Antwort oder noch expliziter: "INSERT INTO X.TABLE (ID, Wert) SELECT ID, Wert FROM Y.TABLE; Dies funktionierte gut für mich.
Karim Sonbol
@KarimSonbol Der einzige Unterschied besteht darin, dass bei einer akzeptierten Antwort die Übertragung von der Batabase, in der Sie sich befinden, in die angehängte Datenbank erfolgt, während in dieser Antwort umgekehrt ist.
Tulains Córdova
@ TulainsCórdova: Die akzeptierte Antwort (letzte Variante) impliziert, dass sie sich darin unterscheidet, dass sie auch dann funktioniert, wenn "die Spalten nicht in der richtigen Reihenfolge übereinstimmen". Wollen Sie damit sagen, dass das nicht stimmt?
LarsH
51

Einfachster und korrekter Weg in einer einzigen Zeile:

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

Der Primärschlüssel und die Spaltentypen bleiben erhalten.

Bernardo Ramos
quelle
1
Das liegt auf der Hand ... aber wenn es bereits eine Tabelle mit diesem Namen in der Zieldatenbank gibt, ist dies nicht möglich. Es ist also nicht möglich, bereits vorhandene Daten mit dieser Lösung zu ergänzen (ansonsten großartig)
Martin Meeser
@MartinMeeser Bei der Frage geht es darum, die Tabelle zu kopieren und keine Tabellen zusammenzuführen. Sie können versuchen, eine Zusammenführung durchzuführen, indem Sie einen Speicherauszug in eine temporäre Datei erstellen, die Datei bearbeiten, die Anweisung CREATE TABLE entfernen und die temporäre Datei als Eingabe für new.db verwenden. Aber Konflikte um den Primärschlüssel können auftreten
Bernardo Ramos
@MartinMeeser, das Zusammenführen funktioniert tatsächlich. Wenn eine Tabelle in der Ziel-DB vorhanden ist, wird eine Fehlermeldung angezeigt, aber die Daten werden kopiert.
Vincnetas
3
@MartinMeeser in der von mir installierten Version von SQLite (v3.19.3) .dumperstellt den Befehl CREATE TABLE IF NOT EXISTS ...und es tritt kein Fehler auf, obwohl meine Zieltabelle vorhanden ist.
Umgekehrter Ingenieur
1
Einfache, UNIX-freundliche Möglichkeit, das Problem zu lösen. Du verdienst meine Zustimmung. Danke dir!
Augusto Destrero
9

Für eine einmalige Aktion können Sie .dump und .read verwenden.

Speichern Sie die Tabelle my_table aus old_db.sqlite

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

Lesen Sie den Speicherauszug in die Datei new_db.sqlite, sofern die dortige Tabelle nicht vorhanden ist

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

Jetzt haben Sie Ihren Tisch geklont. Um dies für die gesamte Datenbank zu tun, lassen Sie einfach den Tabellennamen im Befehl .dump weg.

Bonus: Die Datenbanken können unterschiedliche Codierungen haben.

Thinkeye
quelle
7

Objective-C-Code zum Kopieren von Tabellen aus einer Datenbank in eine andere Datenbank

-(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
quelle
0

Ich musste Daten aus einer SQL Server Compact-Datenbank nach SQLite verschieben. Mit SQL Server 2008 können Sie also mit der rechten Maustaste auf die Tabelle klicken und "Skripttabelle an" und dann "Daten in Einfügungen" auswählen. Kopieren Sie die Einfügeanweisungen, entfernen Sie die 'GO'-Anweisungen und sie wurden erfolgreich ausgeführt, wenn sie mit der App' DB Browser for Sqlite 'auf die SQLite-Datenbank angewendet wurden.

Michael Gabay
quelle
0

Erstes Szenario: DB1.sqlite und DB2.sqlite haben dieselbe Tabelle (t1), aber DB1 ist "aktueller" als DB2. Wenn es klein ist, löschen Sie die Tabelle aus DB2 und erstellen Sie sie mit den Daten neu:

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

Zweites Szenario: Wenn es sich um eine große Tabelle handelt, ist eine Typlösung möglicherweise besser INSERT if not existsgeeignet. Wenn Sie eine Unique KeySpalte haben, ist dies einfacher, andernfalls müssen Sie eine Kombination von Feldern (möglicherweise jedes Feld) verwenden, und irgendwann ist es immer noch schneller, die Tabelle zu erstellen dropund neu zu erstellen create. Es ist immer einfacher (weniger Nachdenken erforderlich).


DAS SETUP: Öffnen Sie SQLite ohne eine Datenbank, die eine temporaryIn-Memory- mainDatenbank erstellt, dann attachDB1.sqlite und DB2.sqlite

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

und verwenden Sie .databases, um die angehängten Datenbanken und ihre Dateien anzuzeigen.

sqlite> .databases
main: 
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite
Fähiger Mac
quelle
Hinweis: Dies gilt nicht erhalten UNIQUEund PRIMARY KEYAttribute, also wenn Sie die haben, werden Sie entweder müssen DROP TABLEund manuell CREATEund INSERToder die Verwendung .dumpund .read oben genannten Verfahren von @Thinkeye.
Able Mac