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

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

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


当前回答

我很惊讶没有人提到事先准备好的声明。除非您单独使用SQL而不是在任何其他语言中使用,否则我认为将准备好的语句包装在事务中是插入多行最有效的方式。

其他回答

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

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

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

我编写了一些ruby代码,从一系列插入语句中生成一个500个元素的多行插入,这比运行单个插入快得多。然后我尝试简单地将多个插入打包到一个事务中,发现我可以用更少的代码获得同样的速度。

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

如果你正在使用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数据库的最快方法。

在mysql lite中,您不能插入多个值, 但是您可以通过只打开一次连接,然后执行所有插入,然后关闭连接来节省时间。 这样可以节省很多时间