SQLiteデータベース間でのデータのコピー


141

共通のデータを持つ2つのSQLiteデータベースがありますが、目的は異なり、データの再挿入を避けたいので、テーブル全体を1つのデータベースから別のデータベースにコピーできるかどうか疑問に思いましたか?

回答:


170

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;

1
また、SQLite Expertパーソナルプログラムを使用している場合は、右クリックしてデータベースをアタッチする機会が与えられます
mehmet

6
最初にテーブルを作成する必要があります!
クリスルエンゴ2018年

55

allmsa.dbとatlanta.dbの2つのデータベースがある例を考えてみます。データベースallmsa.dbに米国内のすべてのmsasのテーブルがあり、データベースatlanta.dbが空であるとします。

私たちの目標は、テーブルatlantaをallmsa.dbからatlanta.dbにコピーすることです。

手順

  1. sqlite3 atlanta.db(アトランタデータベースに移動するため)
  2. allmsa.dbを添付します。これATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; は、アタッチするデータベースのパス全体を指定するというコマンドノートを使用して行うことができます。
  3. 次のsqlite> .databases ように出力を確認して、データベースリストを確認します。
シーケンス名ファイル                                                      
--- --------------- -------------------------------- --------------------------
0メイン/mnt/fastaccessDS/core/csv/atlanta.db                  
午前2時/mnt/fastaccessDS/core/csv/allmsa.db 
  1. 今、あなたはあなたの実際の目標に到達します。コマンドを使用する INSERT INTO atlanta SELECT * FROM AM.atlanta;

これはあなたの目的に役立つはずです。


2
「INSERT INTO atlanta SELECT * FROM AM.atlanta;」を使用する 物事を台無しにした。すべてのデータをコピーしましたが、一部のフィールドが交換されました!使用しないでください。代わりに、より明示的に受け入れ答えからコマンドを使用するか、または:「INSERT INTO X.TABLE(ID、バリュー)SELECT ID、Y.TABLEから値;私のためにこの加工した罰金。
カリムSonbol

@KarimSonbol唯一の違いは、受け入れられた回答では、転送されたデータベースから添付データベースに転送されますが、この回答ではその逆です。
TulainsCórdova14年

@TulainsCórdova:受け入れられた回答(最後のバリアント)は、「列が順番に一致していない」場合でも機能するという点で異なることを意味します。それは真実ではないと言っていますか?
LarsH

52

1行で最も簡単で正しい方法:

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

主キーと列タイプは保持されます。


1
これは明白なことですが... target-databaseにその名前のテーブルが既に存在する場合、それは不可能です。そのため、そのソリューションを使用して既存のデータに追加することはできません(それ以外の場合は素晴らしい)
Martin Meeser

@MartinMeeser問題は、テーブルをマージするのではなく、テーブルをコピーすることです。一時ファイルにダンプし、ファイルを編集してCREATE TABLEステートメントを削除し、一時ファイルをnew.dbの入力として使用することで、マージを試みることができます。しかし、主キーの競合が発生する可能性があります
Bernardo Ramos

@MartinMeeser、実際にはマージが機能し、テーブルがターゲットDBに存在する場合、エラーメッセージが表示されますが、データはコピーされます。
Vincnetas

3
インストールしたSQLiteのバージョン(v3.19.3)の@MartinMeeser .dumpはコマンドを作成しCREATE TABLE IF NOT EXISTS ...、宛先テーブルが存在していてもエラーは発生しません。
リバースエンジニア、

1
問題を解決するためのシンプルでUNIXフレンドリーな方法。あなたは私の賛成に値する。ありがとうございました!
Augusto Destrero

9

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コマンドでテーブル名を省略します。

おまけ:データベースは異なるエンコーディングを持つことができます。


7

データベースから別のデータベースにテーブルをコピーするための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);
        }
 }

0

SQLサーバーのコンパクトデータベースからsqliteにデータを移動する必要があったので、SQLサーバー2008を使用して、テーブルを右クリックし、[スクリプトテーブル]、[挿入するデータ]の順に選択します。insertステートメントをコピーして 'GO'ステートメントを削除し、 'DB Browser for Sqlite'アプリを使用してsqliteデータベースに適用すると、ステートメントは正常に実行されました。


0

最初のシナリオ: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を開き、次にattachDB1.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

注:これはUNIQUEPRIMARY KEY属性を保持しないので、それらがある場合はDROP TABLE、手動CREATEで行うINSERTか、@ Thinkeyeで前述し.dumpand .read メソッドを使用する必要があります。
Able Mac
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.