Bir SQLite veritabanından diğerine veri kopyalama


141

Ortak verilerle ama farklı amaçlarla 2 SQLite veritabanları var ve verileri yeniden yerleştirmekten kaçınmak istedim, bu yüzden tüm tabloyu bir veritabanından diğerine kopyalamanın mümkün olup olmadığını merak ediyordum?

Yanıtlar:


171

ATTACH komutunu kullanarak Database X'i Database Y ile eklemeniz , ardından aktarmak istediğiniz tablolar için uygun Insert Into komutlarını çalıştırmanız gerekir.

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

Veya sütunlar sırayla eşleşmezse:

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

1
Ayrıca SQLite Uzman Kişisel programı kullanıyorsa, sağ tıklama ve ATTACH veritabanlarına bir şans verir
mehmet

6
Önce tabloyu oluşturmalısınız!
Cris Luengo

55

Allmsa.db ve atlanta.db adlı iki veritabanımın olduğu bir örneği ele alalım. Allmsa.db veritabanının ABD'deki tüm MSA'lar için tabloları olduğunu ve atlanta.db veritabanı boş olduğunu varsayalım.

Hedefimiz atlanta tablosunu allmsa.db'den atlanta.db'ye kopyalamaktır.

adımlar

  1. sqlite3 atlanta.db (atlanta veritabanına gitmek için)
  2. Allmsa.db dosyasını ekleyin. Bu, eklenecek ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; veritabanının tüm yolunu verdiğimiz komut notu kullanılarak yapılabilir .
  3. sqlite> .databases çıktısını görmek için kullanarak veritabanı listesini kontrol edin
sıra ad dosyası                                                      
--- --------------- -------------------------------- --------------------------
0 ana /mnt/fastaccessDS/core/csv/atlanta.db                  
02:00 / mnt/fastaccessDS/core/csv/allmsa.db 
  1. şimdi asıl hedefinize geldiniz. Komutu kullanın INSERT INTO atlanta SELECT * FROM AM.atlanta;

Bu sizin amacınıza hizmet etmelidir.


2
'INSERT INTO atlanta SELECT * FROM AM.atlanta'; şeyleri berbat etti. Tüm verileri kopyaladı, ancak bazı alanlar değiştirildi! Kullanma. Bunun yerine, kabul edilen yanıttaki komutu veya daha da açık bir şekilde kullanın: "X.TABLE'E GİRİN (Id, Değer) SELECT Id, Y.TABLE'dan Değer; Bu benim için iyi çalıştı.
Karim Sonbol

@KarimSonbol Tek fark, kabul edilen cevap transferinde, içinde bulunduğunuz veritabanından, ekli veritabanına yapılırken, bu cevapta başka bir yol var.
Tulains Córdova

@ TulainsCórdova: Kabul edilen cevap (son varyant), "sütunlar sırayla eşleşmediğinde" bile farklı olmasının farklı olduğunu ima eder. Bunun doğru olmadığını mı söylüyorsun?
LarsH

52

Tek bir hat üzerinde en kolay ve doğru yol:

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

Birincil anahtar ve sütun türleri korunacaktır.


1
Bu açıktır ... ancak hedef veritabanında bu ada sahip bir tablo varsa, bu mümkün değildir. Dolayısıyla bu çözümle mevcut verilere eklemek mümkün değildir (aksi halde harika)
Martin Meeser

@MartinMeeser Soru tabloları birleştirmeyen tabloyu kopyalamakla ilgilidir. Geçici bir dosyaya atlayarak, CREATE TABLE deyimini kaldırarak dosyayı düzenleyerek ve geçici dosyayı new.db için girdi olarak kullanarak birleştirmeyi deneyebilirsiniz. Ancak birincil anahtarda çatışmalar olabilir
Bernardo Ramos

@MartinMeeser, aslında birleştirme çalışır, hedef DB'de tablo varsa hata mesajı alırsınız, ancak veriler kopyalanır.
Vincnetas

3
@MartinMeeser yüklediğim SQLite sürümünde (v3.19.3), .dumpkomutu oluşturur ve hedef tablom CREATE TABLE IF NOT EXISTS ...olmasına rağmen hata yok.
Ters Mühendis

1
Sorunu çözmek için basit, UNIX dostu bir yol. Benim oyumu hak ediyorsun. Teşekkür ederim!
Augusto Destrero

10

Bir kerelik işlem için .dump ve .read kullanabilirsiniz.

My_table tablosunu old_db.sqlite sayfasından dök

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

Tablonun mevcut olmadığını varsayarak new_db.sqlite dosyasına dökümü okuyun

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

Şimdi masanızı klonladınız. Tüm veritabanı için bunu yapmak için, tablo adını .dump komutunda bırakmanız yeterlidir.

Bonus: Veritabanları farklı kodlamalara sahip olabilir.


7

Tabloyu bir veritabanından başka bir veritabanına kopyalamak için Objective-C kodu

-(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

Bir sql server kompakt veritabanından sqlite veri taşımak gerekiyordu, bu yüzden sql server 2008 kullanarak masaya sağ tıklayın ve 'Komut Dosyası Tablosu' ve sonra 'Veri Ekler' seçin. Insert deyimlerini kopyalayın 'GO' deyimlerini kaldırın ve sqlite veritabanına uygulandığında 'Sqlite için DB Tarayıcısı' uygulaması kullanılarak başarıyla yürütüldü.


0

İlk senaryo: DB1.sqlite ve DB2.sqlite aynı tabloya (t1) sahiptir, ancak DB1, DB2'den daha "güncel" dir. Küçükse, tabloyu DB2'den bırakın ve verilerle yeniden oluşturun:

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

İkinci senaryo: Büyük bir tabloysa, bir INSERT if not existstür çözümle daha iyi olabilirsiniz . Eğer bir varsa Unique Keysütun aksi takdirde (belki her alanda) alanların bir arada kullanmak gerekirdi daha yalındır olduğunu ve bir noktada sadece hala daha hızlıdır dropve yeniden createtablo; her zaman daha basittir (daha az düşünmek gerekir).


AYAR: DB olmadan açık SQLite bir oluşturur temporarybellek içinde main, veritabanı sonra attachDB1.sqlite ve DB2.sqlite

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

ve .databasesekli veritabanlarını ve dosyalarını görmek için kullanın .

sqlite> .databases
main: 
db1: /db/DB1.sqlite
db2: /db/DB2.sqlite

NOT: Bu korumaz UNIQUEve PRIMARY KEYnitelikleri, o varsa o kadar, ya gerekir DROP TABLEelle ve CREATEve INSERTya kullanmak .dumpve .read yukarıda bahsedilen yöntemi @Thinkeye tarafından.
Able Mac
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.