共通のデータを持つ2つのSQLiteデータベースがありますが、目的は異なり、データの再挿入を避けたいので、テーブル全体を1つのデータベースから別のデータベースにコピーできるかどうか疑問に思いましたか?
共通のデータを持つ2つのSQLiteデータベースがありますが、目的は異なり、データの再挿入を避けたいので、テーブル全体を1つのデータベースから別のデータベースにコピーできるかどうか疑問に思いましたか?
回答:
ATTACHコマンドを使用してデータベースXとデータベースYを接続し、転送するテーブルに対して適切なInsert Intoコマンドを実行する必要があります。
INSERT INTO X.TABLE SELECT * FROM Y.TABLE;
または、列が順番に一致しない場合:
INSERT INTO X.TABLE(fieldname1, fieldname2) SELECT fieldname1, fieldname2 FROM Y.TABLE;
allmsa.dbとatlanta.dbの2つのデータベースがある例を考えてみます。データベースallmsa.dbに米国内のすべてのmsasのテーブルがあり、データベースatlanta.dbが空であるとします。
私たちの目標は、テーブルatlantaをallmsa.dbからatlanta.dbにコピーすることです。
ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM;
は、アタッチするデータベースのパス全体を指定するというコマンドノートを使用して行うことができます。sqlite> .databases
ように出力を確認して、データベースリストを確認します。シーケンス名ファイル --- --------------- -------------------------------- -------------------------- 0メイン/mnt/fastaccessDS/core/csv/atlanta.db 午前2時/mnt/fastaccessDS/core/csv/allmsa.db
INSERT INTO atlanta SELECT * FROM AM.atlanta;
これはあなたの目的に役立つはずです。
1行で最も簡単で正しい方法:
sqlite3 old.db ".dump mytable" | sqlite3 new.db
主キーと列タイプは保持されます。
.dump
はコマンドを作成しCREATE TABLE IF NOT EXISTS ...
、宛先テーブルが存在していてもエラーは発生しません。
1回限りのアクションでは、.dumpおよび.readを使用できます。
old_db.sqliteからテーブルmy_tableをダンプします。
c:\sqlite>sqlite3.exe old_db.sqlite
sqlite> .output mytable_dump.sql
sqlite> .dump my_table
sqlite> .quit
存在するテーブルが存在しないと想定して、ダンプをnew_db.sqliteに読み込みます。
c:\sqlite>sqlite3.exe new_db.sqlite
sqlite> .read mytable_dump.sql
これで、テーブルのクローンが作成されました。データベース全体でこれを行うには、.dumpコマンドでテーブル名を省略します。
おまけ:データベースは異なるエンコーディングを持つことができます。
データベースから別のデータベースにテーブルをコピーするためのObjective-Cコード
-(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);
}
}
最初のシナリオ:DB1.sqliteとDB2.sqliteには同じテーブル(t1)がありますが、DB1はDB2より「最新」です。小さい場合は、DB2からテーブルをドロップし、データを使用して再作成します。
> DROP TABLE IF EXISTS db2.t1; CREATE TABLE db2.t1 AS SELECT * FROM db1.t1;
2番目のシナリオ:大きなテーブルの場合は、INSERT if not exists
型ソリューションの方がよい場合があります。あなたが持っている場合はUnique Key
、列をそれはそうでなければ、(多分すべてのフィールド)フィールドの組み合わせを使用する必要があるだろう、もっとまっすぐだとどこかの時点でそれだけにはまだ速いだdrop
と再create
テーブルを。それは常により簡単です(必要とされる考えは少なくなります)。
セットアップ:temporary
インメモリmain
データベースを作成するDBなしでSQLiteを開き、次にattach
DB1.sqliteおよびDB2.sqlite
> sqlite3
sqlite> ATTACH "DB1.sqlite" AS db1
sqlite> ATTACH "DB2.sqlite" AS db2
.databases
接続されたデータベースとそのファイルを表示するために使用します。
sqlite> .databases
main:
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite