Copiando dados de um banco de dados SQLite para outro

141

Eu tenho 2 bancos de dados SQLite com dados comuns, mas com propósitos diferentes, e queria evitar a reinserção de dados. Por isso, fiquei pensando se era possível copiar uma tabela inteira de um banco de dados para outro?

Leonardo Marques
fonte

Respostas:

170

Você precisará anexar o Banco de Dados X ao Banco de Dados Y usando o comando ATTACH e , em seguida, execute os comandos Insert Into apropriados para as tabelas que você deseja transferir.

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

Ou, se as colunas não corresponderem na ordem:

INSERT INTO X.TABLE(fieldname1, fieldname2) SELECT fieldname1, fieldname2 FROM Y.TABLE;
Michael D. Irizarry
fonte
1
Além disso, se programa SQLite Especialista pessoal está usando, ele dá a chance de clique direito e anexar bancos de dados
Mehmet
6
Você precisa criar a tabela primeiro!
Cris Luengo
55

Considere um exemplo em que eu tenho dois bancos de dados, como allmsa.db e atlanta.db. Digamos que o banco de dados allmsa.db tenha tabelas para todas as msas nos EUA e o banco de dados atlanta.db esteja vazio.

Nosso objetivo é copiar a tabela atlanta de allmsa.db para atlanta.db.

Passos

  1. sqlite3 atlanta.db (para acessar o banco de dados do atlanta)
  2. Anexe allmsa.db. Isso pode ser feito usando a ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; nota de comando que fornecemos todo o caminho do banco de dados a ser anexado.
  3. verifique a lista de banco de dados usando, sqlite> .databases você pode ver a saída como
arquivo de nome seq                                                      
--- --------------- -------------------------------- --------------------------
0 main /mnt/fastaccessDS/core/csv/atlanta.db                  
2h /mnt/fastaccessDS/core/csv/allmsa.db 
  1. agora você chega ao seu objetivo real. Use o comando INSERT INTO atlanta SELECT * FROM AM.atlanta;

Isso deve servir ao seu propósito.

Neeraj Chandak
fonte
2
Usando 'INSERT INTO atlanta SELECT * FROM AM.atlanta;' estraguei tudo. Ele copiou todos os dados, mas alguns campos foram trocados! Não use. Em vez disso use o comando da resposta aceita, ou mesmo mais explicitamente: ". INSERT INTO X.TABLE (Id, Value) SELECT Id, valor a partir Y.TABLE; Isso funcionou bem para mim
Karim Sonbol
@KarimSonbol A única diferença é que, na transferência de resposta aceita, é feita DA base de dados em que você está, PARA o banco de dados anexado, enquanto que nesta resposta é o contrário.
Tulains Córdova
@ TulainsCórdova: A resposta aceita (última variante) implica que é diferente, pois funciona mesmo quando "as colunas não são correspondidas em ordem". Você está dizendo que isso não é verdade?
LarsH 31/08/19
52

Maneira mais fácil e correta em uma única linha:

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

A chave primária e os tipos de colunas serão mantidos.

Bernardo Ramos
fonte
1
Isso é óbvio ... mas se já existe uma tabela com esse nome no banco de dados de destino, isso não é possível. Portanto, não é possível adicionar aos dados já existentes com essa solução (ótimo outra forma)
Martin Meeser
@MartinMeeser A questão é copiar a tabela e não mesclar tabelas. Você pode tentar mesclar despejando em um arquivo temporário, editando o arquivo removendo a instrução CREATE TABLE e usando o arquivo temporário como entrada para new.db. Mas os conflitos na chave primária pode acontecer
Bernardo Ramos
@MartinMeeser, na verdade, a fusão funciona. Se a tabela existir no banco de dados de destino, você receberá uma mensagem de erro, mas os dados serão copiados.
Vincnetas 27/02/19
3
O @MartinMeeser na versão do SQLite que instalei (v3.19.3), .dumpcria o comando CREATE TABLE IF NOT EXISTS ...e não há erro, mesmo que minha tabela de destino exista.
Engenheiro reverso
1
Maneira simples e amigável para UNIX de resolver o problema. Você merece o meu voto positivo. Obrigado!
Augusto Destrero 24/10/19
9

Para uma ação única, você pode usar .dump e .read.

Despejar a tabela my_table de old_db.sqlite

c:\sqlite>sqlite3.exe old_db.sqlite
sqlite> .output mytable_dump.sql
sqlite> .dump my_table
sqlite> .quit

Leia o dump no new_db.sqlite assumindo que a tabela não exista

c:\sqlite>sqlite3.exe new_db.sqlite
sqlite> .read mytable_dump.sql

Agora você clonou sua mesa. Para fazer isso em todo o banco de dados, simplesmente deixe de fora o nome da tabela no comando .dump.

Bônus: os bancos de dados podem ter codificações diferentes.

Thinkeye
fonte
7

Código Objective-C para copiar a tabela de um banco de dados para outro banco de dados

-(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);
        }
 }
avinash
fonte
0

Eu precisava mover dados de um banco de dados compacto do servidor sql para o sqlite, portanto, usando o sql server 2008, você pode clicar com o botão direito do mouse na tabela e selecionar 'Tabela de scripts para' e 'Dados para inserções'. Copie as instruções insert e remova as instruções 'GO' e ela foi executada com êxito quando aplicada ao banco de dados sqlite usando o aplicativo 'DB Browser for Sqlite'.

Michael Gabay
fonte
0

Primeiro cenário: DB1.sqlite e DB2.sqlite têm a mesma tabela (t1), mas o DB1 está mais "atualizado" que o DB2. Se for pequeno, solte a tabela do DB2 e recrie-a com os dados:

> DROP TABLE IF EXISTS db2.t1; CREATE TABLE db2.t1 AS SELECT * FROM db1.t1;

Segundo cenário: se for uma tabela grande, é melhor você usar uma INSERT if not existssolução de tipo. Se você tiver uma Unique Keycoluna, é mais direta; caso contrário, você precisará usar uma combinação de campos (talvez todos os campos) e, em algum momento, ainda será mais rápido apenas droprefazer createa tabela; é sempre mais direto (menos pensamento é necessário).


A CONFIGURAÇÃO: abra o SQLite sem um banco de dados que crie um banco de dados temporaryna memória e main, em seguida, attachDB1.sqlite e DB2.sqlite

> sqlite3
sqlite> ATTACH "DB1.sqlite" AS db1
sqlite> ATTACH "DB2.sqlite" AS db2

e use .databasespara ver os bancos de dados anexados e seus arquivos.

sqlite> .databases
main: 
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite
Capaz de Mac
fonte
NOTA: Isso não preserva UNIQUEnem PRIMARY KEYatribui atributos; portanto, se você os tiver, precisará DROP TABLEe manualmente CREATEe / INSERTou usará o método.dump e .read mencionado acima por @Thinkeye.
Able Mac