在MySQL中,你可以像这样插入多行:

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

然而,当我尝试这样做时,我得到了一个错误。是否可以在SQLite数据库中一次插入多行?这样做的语法是什么?


当前回答

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中使用了一个循环,而不是使用CLI .import命令,那么一定要遵循sqlite FAQ中的建议来提高INSERT速度:

By default, each INSERT statement is its own transaction. But if you surround multiple INSERT statements with BEGIN...COMMIT then all the inserts are grouped into a single transaction. The time needed to commit the transaction is amortized over all the enclosed insert statements and so the time per insert statement is greatly reduced. Another option is to run PRAGMA synchronous=OFF. This command will cause SQLite to not wait on data to reach the disk surface, which will make write operations appear to be much faster. But if you lose power in the middle of a transaction, your database file might go corrupt.

其他回答

如果你正在使用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;

它是如何工作的? 它使用if表选项卡:

id int
------
1
2

然后从TAB a中选择a.id, b.id, 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数据库的最快方法。

你可以使用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/

编辑: 从API级别17开始,InsertHelper已弃用

是的,sql可以做到这一点,但是使用不同的语法。顺便说一下,sqlite文档非常好。它还会告诉您插入几行的唯一方法是使用select语句作为要插入的数据的源。

正如其他人所说,SQLite不支持这种语法。我不知道复合insert是否是SQL标准的一部分,但根据我的经验,它们在许多产品中都没有实现。

顺便说一句,您应该意识到,如果在显式事务中包装多个INSERT, SQLite中的INSERT性能将大大提高。

从版本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:请给Brian Campbell的回复+1。不是我的!他首先提出了解决方案。