เป็นไปได้หรือไม่ที่จะแทรกหลายแถวในฐานข้อมูล SQLite?


551

ใน MySQL คุณสามารถแทรกหลายแถวดังนี้

INSERT INTO 'tablename' ('column1', 'column2') VALUES
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2');

อย่างไรก็ตามฉันได้รับข้อผิดพลาดเมื่อพยายามทำสิ่งนี้ เป็นไปได้หรือไม่ที่จะแทรกหลายแถวในฐานข้อมูล SQLite? ไวยากรณ์ที่จะทำคืออะไร?


26
ไม่ใช่ dupe เนื่องจากคำถามนี้ถามเกี่ยวกับ SQLite โดยเฉพาะซึ่งตรงข้ามกับ SQL โดยทั่วไป (แม้ว่าบางคำตอบของคำถามนั้นมีประโยชน์สำหรับอันนี้)
Brian Campbell

5
บนเม็ดมีดจำนวนมาก: stackoverflow.com/questions/1711631/…
tuinstoel

5
คำถามคือทำไมคุณควรทำอย่างนั้น ในขณะที่ SQlite อยู่ระหว่างการดำเนินการบนเครื่องเดียวกันและคุณสามารถใส่เม็ดมีดหลายใบลงในธุรกรรมที่ฉันไม่ต้องการ
andig

2
ใช่เริ่มจากรุ่น 2012-03-20 (3.7.11) สนับสนุนไวยากรณ์ของคุณแล้ว
mjb

คำตอบ:


607

ปรับปรุง

ในฐานะที่เป็นจุด BrianCampbell ออกจากที่นี่ , SQLite 3.7.11 ขึ้นไปในขณะนี้สนับสนุนไวยากรณ์ที่เรียบง่ายของโพสต์ต้นฉบับ อย่างไรก็ตามวิธีการที่แสดงยังคงเหมาะสมถ้าคุณต้องการความเข้ากันได้สูงสุดในฐานข้อมูลดั้งเดิม

คำตอบเดิม

ถ้าฉันมีสิทธิ์ของผมจะชนการตอบกลับของแม่น้ำ : คุณสามารถแทรกหลายแถวใน SQLite คุณเพียงแค่ต้องไวยากรณ์ที่แตกต่างกัน เพื่อให้ชัดเจนอย่างสมบูรณ์ตัวอย่างของ OPs MySQL:

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2');

สิ่งนี้สามารถนำไปหล่อหลอมเป็น SQLite ใหม่ได้:

     INSERT INTO 'tablename'
          SELECT 'data1' AS 'column1', 'data2' AS 'column2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'

หมายเหตุเกี่ยวกับประสิทธิภาพ

ฉันใช้เทคนิคนี้เพื่อโหลดชุดข้อมูลขนาดใหญ่จาก Ruby on Rails อย่างมีประสิทธิภาพ อย่างไรก็ตาม , เป็นไจคุกชี้ให้เห็นก็ไม่ชัดเจนนี้เป็นเร็ว ๆ ห่อบุคคลINSERTsภายในรายการเดียว:

BEGIN TRANSACTION;
INSERT INTO 'tablename' table VALUES ('data1', 'data2');
INSERT INTO 'tablename' table VALUES ('data3', 'data4');
...
COMMIT;

หากประสิทธิภาพเป็นเป้าหมายของคุณคุณควรลองสิ่งนี้ก่อน

หมายเหตุเกี่ยวกับ UNION กับ UNION ALL

ในฐานะที่เป็นคนหลายคนให้ความเห็นว่าถ้าคุณใช้UNION ALL(ดังแสดงด้านบน) data1, data2แถวทั้งหมดจะถูกแทรกดังนั้นในกรณีนี้คุณจะได้รับสี่แถว หากคุณข้ามไปALLแถวที่ซ้ำกันจะถูกตัดออก (และการดำเนินการจะช้าลงเล็กน้อย) เราใช้ยูเนี่ยนทั้งหมดเพราะมันตรงกับความหมายของโพสต์ต้นฉบับมากขึ้น

ในการปิด

PS: กรุณา +1 คำตอบของแม่น้ำเพราะมันนำเสนอวิธีการแก้ปัญหาก่อน


102
ในฐานะที่เป็นโน้ตเพิ่มเติม sqlite ดูเหมือนว่าจะสนับสนุนสหภาพดังกล่าวมากถึง 500 รายการต่อการค้นหาดังนั้นหากคุณพยายามที่จะโยนข้อมูลมากกว่าที่คุณจะต้องแบ่งออกเป็น 500 บล็อกองค์ประกอบ ( sqlite.org/limits.html )
Jamie Cook

3
ตกลง: SQLite ไม่ใช่คอขวดเป็นค่าใช้จ่ายของธุรกรรม ORM แต่ละรายการ (ในกรณีของฉันคือ Ruby On Rails) ดังนั้นมันจึงยังคงเป็นชัยชนะที่ยิ่งใหญ่
fearless_fool

3
โซลูชันนี้หรือโซลูชัน 3.7.11 เปรียบเทียบกับการใช้บล็อกธุรกรรมได้อย่างไร มันจะเร็วไปinsert into t values (data),(data),(data)หรือbegin transaction; insert into t values (data);insert into t values (data);insert into t values (data);Commit;?
ด่าน

5
หมายเหตุเพิ่มเติม: ระวัง! ไวยากรณ์นี้จะลบแถวที่ซ้ำกัน! ใช้UNION ALLเพื่อหลีกเลี่ยงปัญหานั้น (หรือเพื่อประสิทธิภาพที่เพิ่มขึ้นเล็กน้อย)
chacham15

1
@Shadowfax เพื่อตรวจสอบเวอร์ชัน SQLite ดูที่sqlite3.sqlite_version(ควรเป็น 3.7.x หรือ 3.8.x) ไม่ใช่sqlite3.version(ซึ่งเป็นเพียงรุ่นของโมดูล python)
สูงสุด

562

ใช่เป็นไปได้ แต่ไม่ใช่ด้วยค่าการแทรกที่คั่นด้วยเครื่องหมายจุลภาคปกติ

ลองสิ่งนี้ ...

insert into myTable (col1,col2) 
     select aValue as col1,anotherValue as col2 
     union select moreValue,evenMoreValue 
     union...

ใช่มันน่าเกลียด แต่ก็ง่ายพอที่จะทำให้การสร้างคำสั่งเป็นไปโดยอัตโนมัติจากชุดของค่า นอกจากนี้ดูเหมือนว่าคุณจะต้องประกาศชื่อคอลัมน์ในตัวเลือกแรกเท่านั้น


36
กรุณาใช้ไม่ได้UNION ALL UNIONยกเว้นถ้าคุณต้องการลบรายการที่ซ้ำ
เบอนัวต์

4
ถ้าคุณต้องการให้ ID เพิ่มขึ้นอัตโนมัติให้ตั้งค่า NULL ให้พวกเขา
lenooh

241

ใช่ SQLite 3.7.11ได้รับการสนับสนุนใน SQLite จากเอกสารประกอบ SQLite :

ไวยากรณ์คำสั่ง SQLite INSERT

(เมื่อคำตอบนี้ถูกเขียนขึ้นครั้งแรกก็ไม่ได้รับการสนับสนุน)

เพื่อความเข้ากันได้กับ SQLite เวอร์ชันเก่าคุณสามารถใช้เคล็ดลับที่แนะนำโดยandyและfearless_foolโดยใช้UNIONแต่สำหรับ 3.7.11 และใหม่กว่าควรใช้ไวยากรณ์ที่ง่ายกว่าที่อธิบายไว้ที่นี่


3
ผมจะบอกว่า Diagramm VALUESช่วยให้หลายแถวเป็นมีวงปิดด้วยเครื่องหมายจุลภาคนอกวงเล็บหลัง
Johannes Gerer

@JohannesGerer พวกเขาอัปเดตภาพนี้ตั้งแต่ฉันฝังมัน ท่านสามารถเข้าดูแผนภาพในเวลาที่ฉันฝังมันในอินเทอร์เน็ตเอกสารเก่า ในความเป็นจริงเมื่อสองเดือนที่แล้วพวกเขาเพิ่มการสนับสนุนหลายแถวในส่วนแทรกและเมื่อสองวันก่อนที่พวกเขาเปิดตัวรุ่นที่มีการเปลี่ยนแปลงนั้น ฉันจะอัปเดตคำตอบของฉันตาม
Brian Campbell

1
@Brian คุณช่วยกรุณาอ้างอิงข้อความเอกสาร SQLite ที่ระบุว่าเป็นไปได้หรือไม่ ฉันอ่านเอกสาร 3 ครั้งและไม่พบสิ่งใดเกี่ยวกับการแทรกหลายแถว แต่มีเพียงรูปนี้ (และไม่มีอะไรเกี่ยวกับเครื่องหมายจุลภาคVALUES (...), (...)) :(
Prizoff

1
@Prizoff ฉันเชื่อมโยงกับการกระทำที่เพิ่มการสนับสนุนนี้รวมถึงกรณีทดสอบ คุณสามารถเห็นได้ในแผนภาพ (เปรียบเทียบลิงค์ IA ) ว่ามีวนรอบนิพจน์หลังVALUESแสดงว่าสามารถคั่นด้วยเครื่องหมายจุลภาคซ้ำได้ และฉันเชื่อมโยงกับบันทึกย่อประจำรุ่นสำหรับเวอร์ชันที่เพิ่มคุณสมบัติซึ่งระบุว่า "ปรับปรุงไวยากรณ์ INSERT เพื่อให้สามารถแทรกหลายแถวผ่านทางส่วนคำสั่ง VALUES"
Brian Campbell

1
@Prizoff ผมกล่าวถึงนี้เพื่อดูแล SQLite เขามีความมุ่งมั่นแก้ไขปัญหาซึ่งเป็นที่มีอยู่ในเอกสารร่าง ฉันเดาว่ามันจะอยู่ในเอกสารอย่างเป็นทางการในรุ่นถัดไป
Brian Campbell

57

ฉันเขียนรหัสทับทิมเพื่อสร้างการแทรกแบบหลายแถว 500 องค์ประกอบจากชุดคำสั่งการแทรกที่เร็วกว่าการรันเม็ดมีดแต่ละชุด จากนั้นฉันก็ลองใส่เม็ดมีดหลายอันในธุรกรรมเดียวและพบว่าฉันสามารถเพิ่มความเร็วได้เหมือนกันโดยใช้รหัสน้อยกว่ามาก

BEGIN TRANSACTION;
INSERT INTO table VALUES (1,1,1,1);
INSERT INTO table VALUES (2,2,2,2);
...
COMMIT;

1
แต่สิ่งนี้ไม่ทำงานในรหัสในขณะที่มันทำงานโดยตรงในตัวจัดการ SQLite ในรหัสมันแทรกแถวที่ 1 เท่านั้น :(
Vaibhav Saran

4
ฉันใช้รูปแบบการแทรกในรหัสของฉันและมันทำงานได้อย่างสมบูรณ์ คุณต้องทำให้แน่ใจว่าคุณส่ง SQL ทั้งหมดในครั้งเดียว นี่เป็นการเพิ่มความเร็วอย่างมากสำหรับฉัน แต่ฉันอยากรู้ว่าคำตอบที่ยอมรับนั้นเร็วหรือช้ากว่านี้ไหม
ด่าน

วิธีการนี้ปรับขนาดได้ดีมากเมื่อทำการปรับเปลี่ยนตารางหลายตารางภายในธุรกรรมเดียวซึ่งฉันพบว่าตัวเองกำลังทำบ่อยครั้งเมื่อแบตช์โหลดฐานข้อมูล
แฟรงก์

รับทราบว่าวิธีการนี้จะไม่ทำงานหากคุณจำเป็นต้องใช้ผูก SQLite3 Engine จะสมมติว่าการเชื่อมโยงทั้งหมดของคุณจะใช้กับคำสั่งแรกและไม่สนใจคำสั่งต่อไปนี้ ดูคำถาม SOนี้สำหรับคำอธิบายโดยละเอียดเพิ่มเติม
Philippe Hebert

38

ตามหน้านี้ไม่ได้รับการสนับสนุน:

  • 2007-12-03: ไม่สนับสนุน INSERT หลายแถวหรือ INSERT ไม่รองรับ INSERT
  INSERT INTO table (col1, col2) VALUES 
      ('row1col1', 'row1col2'), ('row2col1', 'row2col2'), ...

ที่จริงแล้วตามมาตรฐาน SQL92 นิพจน์ค่าควรจะสามารถยืนบนตัวเอง ตัวอย่างเช่นต่อไปนี้ควรกลับตารางหนึ่งคอลัมน์ที่มีสามแถว:VALUES 'john', 'mary', 'paul';

ขณะที่รุ่น 3.7.11 SQLite ไม่สนับสนุนหลายแถวแทรก ความคิดเห็น Richard Hipp:

"เม็ดมีดที่มีหลายค่าใหม่นั้นเป็นเพียง suger แบบวากยสัมพันธ์ (sic) สำหรับเม็ดมีดผสมไม่มีข้อได้เปรียบด้านประสิทธิภาพอย่างใดอย่างหนึ่งหรืออย่างอื่น"


ไม่มีข้อได้เปรียบด้านประสิทธิภาพการทำงานไม่ทางใดก็ทางหนึ่ง - คุณสามารถบอกฉันว่าคุณเห็นคำพูดนั้นอยู่ที่ไหน ฉันไม่พบที่ใดก็ได้
Alix Axel

15

เริ่มจากรุ่น 2012-03-20 (3.7.11), sqlite รองรับไวยากรณ์ INSERT ต่อไปนี้:

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data3', 'data4'),
  ('data5', 'data6'),
  ('data7', 'data8');

อ่านเอกสาร: http://www.sqlite.org/lang_insert.html

PS: โปรด +1 เพื่อตอบ / ตอบของ Brian Campbell ไม่ใช่ของฉัน! เขาเสนอวิธีแก้ปัญหาก่อน


10

ดังที่ผู้โพสต์คนอื่น ๆ ได้กล่าวไว้ SQLite ไม่สนับสนุนไวยากรณ์นี้ ฉันไม่ทราบว่า INSERT แบบผสมเป็นส่วนหนึ่งของมาตรฐาน SQL หรือไม่ แต่จากประสบการณ์ของฉันพวกเขาไม่ได้นำไปใช้กับผลิตภัณฑ์จำนวนมาก

นอกเหนือจากนี้คุณควรทราบว่าประสิทธิภาพของ INSERT ใน SQLite นั้นได้รับการปรับปรุงให้ดีขึ้นอย่างมากถ้าคุณใส่ INSERT หลาย ๆ อันในธุรกรรมที่ชัดเจน


10

ใช่ sql สามารถทำได้ แต่ด้วยรูปแบบที่แตกต่างกัน เอกสาร SQLiteสวยดีโดยวิธีการ มันจะบอกคุณด้วยว่าวิธีเดียวที่จะแทรกหลายแถวคือใช้คำสั่ง selectเป็นแหล่งข้อมูลที่จะแทรก


9

Sqlite3 ไม่สามารถทำได้โดยตรงใน SQL ยกเว้นผ่าน SELECT และในขณะที่ SELECT สามารถส่งคืน "แถว" ของการแสดงออกฉันรู้ว่าไม่มีวิธีที่จะทำให้มันกลับมาเป็นคอลัมน์ปลอม

อย่างไรก็ตาม CLI สามารถทำได้:

.import FILE TABLE     Import data from FILE into TABLE
.separator STRING      Change separator used by output mode and .import

$ sqlite3 /tmp/test.db
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> create table abc (a);
sqlite> .import /dev/tty abc
1
2
3
99
^D
sqlite> select * from abc;
1
2
3
99
sqlite> 

หากคุณใส่วนรอบ INSERT แทนที่จะใช้.importคำสั่งCLI ให้แน่ใจว่าได้ปฏิบัติตามคำแนะนำใน sqlite FAQ สำหรับความเร็ว INSERT:

ตามค่าเริ่มต้นคำสั่ง INSERT แต่ละรายการจะเป็นธุรกรรมของตนเอง แต่ถ้าคุณล้อมรอบคำสั่ง INSERT หลายรายการด้วย BEGIN ... COMMIT เม็ดมีดทั้งหมดจะถูกจัดกลุ่มเป็นธุรกรรมเดียว เวลาที่ใช้ในการส่งมอบธุรกรรมจะถูกตัดจำหน่ายตามคำสั่งแทรกที่แนบมาทั้งหมดดังนั้นเวลาต่อคำสั่งแทรกจะลดลงอย่างมาก

อีกตัวเลือกหนึ่งคือเรียกใช้ PRAGMA synchronous = OFF คำสั่งนี้จะทำให้ SQLite ไม่ต้องรอข้อมูลเพื่อเข้าถึงพื้นผิวดิสก์ซึ่งจะทำให้การดำเนินการเขียนเร็วขึ้นมาก แต่ถ้าคุณสูญเสียพลังงานในระหว่างการทำธุรกรรมไฟล์ฐานข้อมูลของคุณอาจเสียหาย


หากคุณดูซอร์สโค้ดสำหรับ.importคำสั่งของ SQLite มันเป็นเพียงลูปอ่านบรรทัดจากไฟล์อินพุต (หรือ tty) จากนั้นมีคำสั่ง INSERT สำหรับบรรทัดนั้น น่าเสียดายที่ไม่มีการปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญ
Bill Karwin

8

อเล็กซ์ถูกต้อง: คำสั่ง "เลือก ... สหภาพ" จะสูญเสียการสั่งซื้อซึ่งสำคัญมากสำหรับผู้ใช้บางคน แม้ว่าคุณจะแทรกในคำสั่งเฉพาะ sqlite จะเปลี่ยนสิ่งต่าง ๆ เพื่อให้ชอบใช้ธุรกรรมถ้าการเรียงคำสั่งเป็นสิ่งสำคัญ

create table t_example (qid int not null, primary key (qid));
begin transaction;
insert into "t_example" (qid) values (8);
insert into "t_example" (qid) values (4);
insert into "t_example" (qid) values (9);
end transaction;    

select rowid,* from t_example;
1|8
2|4
3|9

8

fearless_fool มีคำตอบที่ยอดเยี่ยมสำหรับเวอร์ชั่นที่เก่ากว่า ฉันแค่อยากจะเพิ่มว่าคุณต้องแน่ใจว่าคุณมีคอลัมน์ทั้งหมดที่ระบุไว้ ดังนั้นหากคุณมี 3 คอลัมน์คุณต้องแน่ใจว่าการกระทำที่เลือกไว้ใน 3 คอลัมน์

ตัวอย่าง: ฉันมี 3 คอลัมน์ แต่ฉันต้องการแทรกข้อมูล 2 คอลัมน์เท่านั้น สมมติว่าฉันไม่สนใจคอลัมน์แรกเพราะมันเป็นเลขจำนวนเต็มมาตรฐาน ฉันสามารถทำสิ่งต่อไปนี้ ...

INSERT INTO 'tablename'
      SELECT NULL AS 'column1', 'data1' AS 'column2', 'data2' AS 'column3'
UNION SELECT NULL, 'data3', 'data4'
UNION SELECT NULL, 'data5', 'data6'
UNION SELECT NULL, 'data7', 'data8'

หมายเหตุ: โปรดจำไว้ว่าคำสั่ง "select ... union" จะสูญเสียการสั่งซื้อ (จาก AG1)



6

คุณทำไม่ได้ แต่ฉันไม่คิดว่าคุณจะพลาดอะไร

เนื่องจากคุณเรียกใช้ sqlite อยู่ตลอดเวลากระบวนการเกือบจะไม่สำคัญกับประสิทธิภาพไม่ว่าคุณจะเรียกใช้คำสั่งแทรก 1 คำสั่งหรือ 100 คำสั่งแทรก การกระทำใช้เวลานานดังนั้นใส่ 100 เม็ดที่แทรกเข้าไปในการทำธุรกรรม

Sqlite เร็วขึ้นมากเมื่อคุณใช้การสืบค้นแบบมีพารามิเตอร์ (จำเป็นต้องแยกวิเคราะห์น้อยกว่า) ดังนั้นฉันจะไม่เชื่อมคำสั่งขนาดใหญ่แบบนี้:

insert into mytable (col1, col2)
select 'a','b'
union 
select 'c','d'
union ...

พวกเขาจะต้องมีการแยกวิเคราะห์อีกครั้งและอีกครั้งเพราะทุกคำตัดแบ่งที่แตกต่างกัน


6

ใน mysql lite คุณไม่สามารถแทรกค่าได้หลายค่า แต่คุณสามารถประหยัดเวลาด้วยการเปิดการเชื่อมต่อเพียงครั้งเดียวจากนั้นทำการแทรกทั้งหมดแล้วปิดการเชื่อมต่อ ช่วยประหยัดเวลาได้มาก


5

ปัญหาเกี่ยวกับการใช้ทรานแซคชันคือคุณล็อกตารางเพื่อการอ่าน ดังนั้นหากคุณมีข้อมูลจำนวนมากที่จะแทรกและคุณจำเป็นต้องเข้าถึงข้อมูลของคุณเพื่อดูตัวอย่างหรือวิธีนี้ใช้งานไม่ได้

ปัญหาเกี่ยวกับการแก้ปัญหาอื่น ๆ คือคุณเสียคำสั่งของการแทรก

insert into mytable (col)
select 'c'
union 
select 'd'
union 
select 'a'
union 
select 'b';

ใน sqlite ข้อมูลจะถูกจัดเก็บ a, b, c, d ...


5

ในฐานะเวอร์ชั่น 3.7.11 SQLite รองรับการแทรกแบบหลายแถว ความคิดเห็น Richard Hipp:

ฉันใช้ 3.6.13

ฉันสั่งเช่นนี้:

insert into xtable(f1,f2,f3) select v1 as f1, v2 as f2, v3 as f3 
union select nextV1+, nextV2+, nextV3+

เมื่อมีการแทรกครั้งละ 50 รายการจะใช้เวลาเพียงไม่กี่วินาทีเท่านั้น

มันเป็นความจริงโดยใช้ sqlite เพื่อแทรกหลายแถวพร้อมกันเป็นไปได้มาก โดย @Andy เขียน

ขอบคุณ Andy +1




2

ฉันมีแบบสอบถามเช่นด้านล่าง แต่ด้วยไดรเวอร์ ODBC SQLite มีข้อผิดพลาดกับ "," มันบอกว่า ฉันรัน vbscript ใน HTA (แอปพลิเคชัน Html)

INSERT INTO evrak_ilac_iliskileri (evrak_id, ilac_id, baglayan_kullanici_id, tarih) VALUES (4150,762,1,datetime()),(4150,9770,1,datetime()),(4150,6609,1,datetime()),(4150,3628,1,datetime()),(4150,9422,1,datetime())

2

บน sqlite 3.7.2:

INSERT INTO table_name (column1, column2) 
                SELECT 'value1', 'value1' 
          UNION SELECT 'value2', 'value2' 
          UNION SELECT 'value3', 'value3' 

และอื่น ๆ


2

ฉันสามารถสร้างคิวรีแบบไดนามิก นี่คือตารางของฉัน:

CREATE TABLE "tblPlanner" ("probid" text,"userid" TEXT,"selectedtime" DATETIME,"plannerid" TEXT,"isLocal" BOOL,"applicationid" TEXT, "comment" TEXT, "subject" TEXT)

และฉันได้รับข้อมูลทั้งหมดผ่าน a JSONดังนั้นหลังจากรับทุกสิ่งภายในNSArrayฉันทำตามสิ่งนี้:

    NSMutableString *query = [[NSMutableString alloc]init];
    for (int i = 0; i < arr.count; i++)
    {
        NSString *sqlQuery = nil;
        sqlQuery = [NSString stringWithFormat:@" ('%@', '%@', '%@', '%@', '%@', '%@', '%@', '%@'),",
                    [[arr objectAtIndex:i] objectForKey:@"plannerid"],
                    [[arr objectAtIndex:i] objectForKey:@"probid"],
                    [[arr objectAtIndex:i] objectForKey:@"userid"],
                    [[arr objectAtIndex:i] objectForKey:@"selectedtime"],
                    [[arr objectAtIndex:i] objectForKey:@"isLocal"],
                    [[arr objectAtIndex:i] objectForKey:@"subject"],
                    [[arr objectAtIndex:i] objectForKey:@"comment"],
                    [[NSUserDefaults standardUserDefaults] objectForKey:@"applicationid"]
                    ];
        [query appendString:sqlQuery];
    }
    // REMOVING LAST COMMA NOW
    [query deleteCharactersInRange:NSMakeRange([query length]-1, 1)];

    query = [NSString stringWithFormat:@"insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values%@",query];

และสุดท้ายแบบสอบถามผลลัพธ์คือ:

insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values 
<append 1>
('pl1176428260', '', 'US32552', '2013-06-08 12:00:44 +0000', '0', 'subj', 'Hiss', 'ap19788'),
<append 2>
('pl2050411638', '', 'US32552', '2013-05-20 10:45:55 +0000', '0', 'TERI', 'Yahoooooooooo', 'ap19788'), 
<append 3>
('pl1828600651', '', 'US32552', '2013-05-21 11:33:33 +0000', '0', 'test', 'Yest', 'ap19788'),
<append 4>
('pl549085534', '', 'US32552', '2013-05-19 11:45:04 +0000', '0', 'subj', 'Comment', 'ap19788'), 
<append 5>
('pl665538927', '', 'US32552', '2013-05-29 11:45:41 +0000', '0', 'subj', '1234567890', 'ap19788'), 
<append 6>
('pl1969438050', '', 'US32552', '2013-06-01 12:00:18 +0000', '0', 'subj', 'Cmt', 'ap19788'),
<append 7>
('pl672204050', '', 'US55240280', '2013-05-23 12:15:58 +0000', '0', 'aassdd', 'Cmt', 'ap19788'), 
<append 8>
('pl1019026150', '', 'US32552', '2013-06-08 12:15:54 +0000', '0', 'exists', 'Cmt', 'ap19788'), 
<append 9>
('pl790670523', '', 'US55240280', '2013-05-26 12:30:21 +0000', '0', 'qwerty', 'Cmt', 'ap19788')

ซึ่งทำงานได้ดีผ่านรหัสและฉันสามารถบันทึกทุกอย่างใน SQLite ได้สำเร็จ

ก่อนหน้านี้ฉันสร้างUNIONคิวรีแบบไดนามิก แต่นั่นทำให้เกิดข้อผิดพลาดทางไวยากรณ์ อย่างไรก็ตามนี่มันทำงานได้ดีสำหรับฉัน


2

ฉันประหลาดใจที่ไม่มีใครได้กล่าวถึงงบเตรียม ถ้าคุณไม่ใช้ SQL ด้วยตัวเองและไม่ใช้ภาษาอื่นฉันก็คิดว่าคำสั่งที่เตรียมไว้ในธุรกรรมจะเป็นวิธีที่มีประสิทธิภาพที่สุดในการแทรกหลายแถว


1
ข้อความที่เตรียมไว้เป็นความคิดที่ดีเสมอ แต่ไม่ใช่ทั้งหมดที่เกี่ยวข้องกับคำถามที่ OP ขอ เขาถามว่าอะไรคือไวยากรณ์พื้นฐานสำหรับการแทรกหลายข้อมูลในหนึ่งคำสั่ง
Lakey

0

คุณสามารถใช้ InsertHelper ได้ง่ายและรวดเร็ว

เอกสาร: http://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html

บทช่วยสอน: http://www.outofwhatbox.com/blog/2010/12/android-using-databaseutils-inserthelper-for-faster-insertions-into-sqlite-database/

แก้ไข: InsertHelper เลิกใช้แล้วในระดับ API 17


3
InsertHelper เลิกใช้แล้วตั้งแต่ API 17
GregM

-1

หากคุณใช้ bash shell คุณสามารถใช้สิ่งนี้:

time bash -c $'
FILE=/dev/shm/test.db
sqlite3 $FILE "create table if not exists tab(id int);"
sqlite3 $FILE "insert into tab values (1),(2)"
for i in 1 2 3 4; do sqlite3 $FILE "INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5"; done; 
sqlite3 $FILE "select count(*) from tab;"'

หรือถ้าคุณอยู่ใน sqlite CLI คุณต้องทำสิ่งนี้:

create table if not exists tab(id int);"
insert into tab values (1),(2);
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
select count(*) from tab;

มันทำงานยังไง? มันทำให้การใช้งานที่ถ้าตารางtab:

id int
------
1
2

จากนั้นselect a.id, b.id from tab a, tab bส่งคืน

a.id int | b.id int
------------------
    1    | 1
    2    | 1
    1    | 2
    2    | 2

และอื่น ๆ หลังจากดำเนินการครั้งแรกเราใส่ 2 แถวจากนั้น 2 ^ 3 = 8 (สามเพราะเรามีtab a, tab b, tab c )

หลังจากการประหารชีวิตครั้งที่สองเราจะแทรกเพิ่มเติม (2+8)^3=1000แถว

หลังจากนั้นสามเราใส่max(1000^3, 5e5)=500000แถวและอื่น ๆ ...

นี่เป็นวิธีที่เร็วที่สุดสำหรับฉันในการสร้างฐานข้อมูล SQLite


2
สิ่งนี้ไม่ทำงานหากคุณต้องการแทรกข้อมูลที่เป็นประโยชน์
CL

@CL มันไม่เป็นความจริง. คุณสามารถผสมกับวันที่สุ่มและรหัสได้ตามต้องการ
ทดสอบ 30
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.