การคัดลอกข้อมูลจากฐานข้อมูล SQLite หนึ่งไปยังอีกฐานข้อมูลหนึ่ง


141

ฉันมีฐานข้อมูล SQLite 2 ตัวที่มีข้อมูลทั่วไป แต่มีจุดประสงค์ที่แตกต่างกันและฉันต้องการหลีกเลี่ยงการแทรกข้อมูลซ้ำดังนั้นฉันสงสัยว่ามันเป็นไปได้ไหมที่จะคัดลอกตารางทั้งหมดจากฐานข้อมูลหนึ่งไปยังอีกฐานข้อมูลหนึ่ง

คำตอบ:


171

คุณจะต้องแนบฐานข้อมูล X กับฐานข้อมูล Y โดยใช้คำสั่งATTACHจากนั้นเรียกใช้คำสั่งแทรกเข้าไปที่เหมาะสมสำหรับตารางที่คุณต้องการถ่ายโอน

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

หรือหากคอลัมน์ไม่ตรงตามลำดับ:

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

1
นอกจากนี้หากโปรแกรม SQLite ผู้เชี่ยวชาญส่วนบุคคลที่ใช้จะช่วยให้โอกาสที่จะคลิกขวาและแนบฐานข้อมูล
เมห์เม็ต

6
คุณต้องสร้างตารางก่อน!
Cris Luengo

55

ลองพิจารณาตัวอย่างที่ฉันมีสองฐานข้อมูลคือ allmsa.db และ atlanta.db สมมติว่าฐานข้อมูล allmsa.db มีตารางสำหรับ msas ทั้งหมดในสหรัฐอเมริกาและฐานข้อมูล atlanta.db ว่างเปล่า

เป้าหมายของเราคือคัดลอกตาราง atlanta จาก allmsa.db ไปยัง atlanta.db

ขั้นตอน

  1. sqlite3 atlanta.db (เพื่อเข้าสู่ฐานข้อมูล atlanta)
  2. แนบ allmsa.db สิ่งนี้สามารถทำได้โดยใช้ATTACH '/mnt/fastaccessDS/core/csv/allmsa.db' AS AM; บันทึกคำสั่งที่เราให้เส้นทางทั้งหมดของฐานข้อมูลที่จะแนบ
  3. ตรวจสอบรายการฐานข้อมูลโดยใช้sqlite> .databases คุณสามารถเห็นผลลัพธ์เป็น
ไฟล์ชื่อ seq                                                      
--- --------------- -------------------------------- --------------------------
0 main /mnt/fastaccessDS/core/csv/atlanta.db                  
2 AM /mnt/fastaccessDS/core/csv/allmsa.db 
  1. ตอนนี้คุณมาถึงเป้าหมายที่แท้จริงของคุณแล้ว ใช้คำสั่ง INSERT INTO atlanta SELECT * FROM AM.atlanta;

สิ่งนี้ควรตอบสนองวัตถุประสงค์ของคุณ


2
ใช้ 'INSERT INTO atlanta SELECT * จาก AM.atlanta;' เลอะสิ่งต่าง ๆ มันคัดลอกข้อมูลทั้งหมด แต่มีการสลับบางฟิลด์! อย่าใช้มัน แทนที่จะใช้คำสั่งจากคำตอบที่ยอมรับหรือมากกว่านั้นอย่างชัดเจน: "INSERT INTO X.TABLE (Id, ค่า) SELECT รหัส, ค่าจาก Y.TABLE; สิ่งนี้ใช้ได้ผลสำหรับฉัน
Karim Sonbol

@KarimSonbol ความแตกต่างเพียงอย่างเดียวคือในการถ่ายโอนคำตอบที่ยอมรับจะทำจากฐานข้อมูลของคุณไปยังฐานข้อมูลที่แนบในขณะที่คำตอบนี้เป็นวิธีอื่น ๆ
Tulains Córdova

@ TulainsCórdova: คำตอบที่ได้รับการยอมรับ (ตัวแปรสุดท้าย) หมายความว่ามันแตกต่างกันในการทำงานแม้ว่า "คอลัมน์จะไม่ตรงตามลำดับ" คุณกำลังบอกว่าไม่เป็นความจริงเหรอ?
LarsH

52

วิธีที่ง่ายที่สุดและถูกต้องในบรรทัดเดียว:

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

คีย์หลักและประเภทคอลัมน์จะถูกเก็บไว้


1
นี่เป็นสิ่งที่ชัดเจน ... แต่ถ้ามีตารางที่มีชื่อนั้นในฐานข้อมูลเป้าหมายอยู่แล้วมันเป็นไปไม่ได้ ดังนั้นจึงเป็นไปไม่ได้ที่จะเพิ่มให้กับข้อมูลที่มีอยู่แล้วกับการแก้ปัญหาที่ (ที่ดีอื่น ๆ )
มาร์ติน Meeser

@MartinMeeser คำถามเกี่ยวกับการคัดลอกตารางที่ไม่รวมตาราง คุณสามารถลองผสานโดยการดัมพ์ไปยังไฟล์ชั่วคราวแก้ไขไฟล์ที่ลบคำสั่ง CREATE TABLE และใช้ไฟล์ชั่วคราวเป็นอินพุตสำหรับ new.db แต่ความขัดแย้งในคีย์หลักอาจเกิดขึ้นได้
Bernardo Ramos

@MartinMeeser การรวมผลงานจริงถ้าตารางมีอยู่ในฐานข้อมูลเป้าหมายคุณจะได้รับข้อความแสดงข้อผิดพลาด แต่ข้อมูลจะถูกคัดลอก
Vincnetas

3
@MartinMeeser ในเวอร์ชันของ SQLite ที่ฉันติดตั้งไว้ (v3.19.3) .dumpสร้างคำสั่งCREATE TABLE IF NOT EXISTS ...และไม่มีข้อผิดพลาดแม้ว่าตารางปลายทางของฉันจะมีอยู่ก็ตาม
วิศวกรที่กลับรายการ

1
วิธีที่ง่ายและเป็นมิตรกับ UNIX ในการแก้ปัญหา คุณสมควรได้รับการโหวตของฉัน ขอบคุณ!
Augusto Destrero

10

สำหรับการกระทำครั้งเดียวคุณสามารถใช้. dump และ .read

ดัมพ์ตาราง my_table จาก old_db.sqlite

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 server 2008 คุณสามารถคลิกขวาบนตารางและเลือก 'Script Table To' แล้วเลือก 'Data to Inserts' คัดลอกคำสั่งแทรกลบคำสั่ง 'GO' และดำเนินการสำเร็จเมื่อนำไปใช้กับฐานข้อมูล sqlite โดยใช้แอป 'DB Browser for 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ตารางอีกครั้ง; มันตรงไปตรงมามากขึ้น (จำเป็นต้องมีการคิดน้อย)


การตั้งค่า: เปิด SQLite โดยไม่ต้อง DB ซึ่งสร้างฐานข้อมูลtemporaryในหน่วยความจำmainจากนั้น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

หมายเหตุ: สิ่งนี้ไม่ได้เก็บรักษาUNIQUEและPRIMARY KEYคุณสมบัติดังนั้นหากคุณมีสิ่งเหล่านั้นคุณจะต้องDROP TABLEและด้วยตนเองCREATEและINSERTหรือใช้.dumpและ.read วิธีการที่กล่าวถึงข้างต้นโดย @Thinkeye
สามารถ Mac
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.