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.
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.
Antworten:
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;
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.
ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM;
, dass wir den gesamten Pfad der anzuhängenden Datenbank angeben.sqlite> .databases
Sie die Ausgabe als sehenseq name file --- --------------- -------------------------------- -------------------------- 0 main /mnt/fastaccessDS/core/csv/atlanta.db 2 Uhr morgens /mnt/fastaccessDS/core/csv/allmsa.db
INSERT INTO atlanta SELECT * FROM AM.atlanta;
Dies sollte Ihren Zweck erfüllen.
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.
.dump
erstellt den Befehl CREATE TABLE IF NOT EXISTS ...
und es tritt kein Fehler auf, obwohl meine Zieltabelle vorhanden ist.
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.
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);
}
}
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.
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 exists
geeignet. Wenn Sie eine Unique Key
Spalte 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 drop
und neu zu erstellen create
. Es ist immer einfacher (weniger Nachdenken erforderlich).
DAS SETUP: Öffnen Sie SQLite ohne eine Datenbank, die eine temporary
In-Memory- main
Datenbank erstellt, dann attach
DB1.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
UNIQUE
und PRIMARY KEY
Attribute, also wenn Sie die haben, werden Sie entweder müssen DROP TABLE
und manuell CREATE
und INSERT
oder die Verwendung .dump
und .read
oben genannten Verfahren von @Thinkeye.