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?
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?
Odpowiedzi:
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;
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.
ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM;
zwróć uwagę, że podajemy całą ścieżkę do bazy danych do dołączenia.sqlite> .databases
możesz zobaczyć dane wyjściowe jakoseq nazwa pliku --- --------------- -------------------------------- -------------------------- 0 main /mnt/fastaccessDS/core/csv/atlanta.db 02:00 /mnt/fastaccessDS/core/csv/allmsa.db
INSERT INTO atlanta SELECT * FROM AM.atlanta;
To powinno służyć twojemu celowi.
Najłatwiejszy i poprawny sposób na jednej linii:
sqlite3 old.db ".dump mytable" | sqlite3 new.db
Klucz podstawowy i typy kolumn zostaną zachowane.
.dump
tworzy polecenie CREATE TABLE IF NOT EXISTS ...
i nie ma błędu, mimo że istnieje moja tabela docelowa.
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.
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);
}
}
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”.
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 exists
zastosujesz rozwiązanie typu. Jeśli masz Unique Key
kolumnę, 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 drop
ponowne create
ustawienie tabeli; jest to zawsze prostsze (wymaga mniej myślenia).
KONFIGURACJA: otwórz SQLite bez bazy danych, która tworzy bazę danych temporary
w pamięci main
, a następnie attach
DB1.sqlite i DB2.sqlite
> sqlite3
sqlite> ATTACH "DB1.sqlite" AS db1
sqlite> ATTACH "DB2.sqlite" AS db2
i użyj, .databases
aby zobaczyć załączone bazy danych i ich pliki.
sqlite> .databases
main:
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite
UNIQUE
i PRIMARY KEY
cechy, więc jeśli masz te, to albo trzeba DROP TABLE
i ręcznie CREATE
i INSERT
czy używać .dump
i .read
metody wymienione powyżej przez @Thinkeye.