将数据从一个SQLite数据库复制到另一个数据库


141

我有2个具有共同数据但用途不同的SQLite数据库,并且我想避免重新插入数据,因此我想知道是否可以将整个表从一个数据库复制到另一个数据库?

Answers:


170

您必须使用ATTACH命令将数据库X与数据库Y附加在一起,然后对要传输的表运行适当的“插入到”命令。

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

或者,如果列不按顺序匹配:

INSERT INTO X.TABLE(fieldname1, fieldname2) SELECT fieldname1, fieldname2 FROM Y.TABLE;

1
同样,如果正在使用SQLite Expert Personal程序,它就有机会右键单击和ATTACH数据库
mehmet

6
您需要先创建表!
Cris Luengo

55

考虑一个示例,其中有两个数据库,即allmsa.db和atlanta.db。假设数据库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 您可以看到输出为
seq名称文件                                                      
----------------- -------------------------------- --------------------------
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唯一的区别是,可接受的答案转移是从您所在的数据库到附加的数据库进行的,而此答案是相反的。
图兰斯·科尔多瓦2014年

@TulainsCórdova:可接受的答案(最后一个变体)意味着它的不同之处在于,即使“列未按顺序匹配”,它也可以工作。你是说那不是真的吗
LarsH

51

一条线上最简单正确的方法:

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

主键和列类型将保留。


1
这很明显……但是,如果目标数据库中已经存在一个具有该名称的表,则不可能。因此,不可能使用该解决方案添加到已经存在的数据中(否则就无法了)
Martin Meeser

@MartinMeeser问题是关于复制表而不是合并表。您可以尝试通过以下方式合并:转储到临时文件,编辑该文件以删除CREATE TABLE语句,并将该临时文件用作new.db的输入。但是主键可能会发生冲突
Bernardo Ramos

@MartinMeeser,实际上是可以合并的,如果目标数据库中存在表,则会收到错误消息,但会复制数据。
Vincnetas

3
我安装的SQLite版本(v3.19.3)中的@MartinMeeser .dump创建命令CREATE TABLE IF NOT EXISTS ...,即使目标表存在也没有错误。
逆向工程师,

1
简单,UNIX友好的解决方法。你应该得到我的支持。谢谢!
奥古斯托·德斯特罗

9

对于一次操作,可以使用.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 server紧凑型数据库移动到sqlite,因此使用sql server 2008可以在表上单击鼠标右键,然后选择“脚本表到”,然后选择“数据插入”。复制插入语句可删除“ GO”语句,当使用“用于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;

第二种情况:如果表很大,使用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

注意:这不会保留UNIQUEPRIMARY KEY属性,因此,如果有这些属性,则需要DROP TABLE手动进行操作CREATEINSERT或者使用@Thinkeye 提及.dumpand .read 方法
Able Mac
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.