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

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

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


当前回答

在sqlite 3.7.2上:

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

等等

其他回答

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

是的,从SQLite 3.7.11开始,SQLite支持这一点。从SQLite文档:

(当这个答案最初写的时候,这是不支持的)

为了兼容旧版本的SQLite,你可以使用andy和fearless_fool所建议的技巧,使用UNION,但对于3.7.11及以后版本,这里描述的更简单的语法应该是首选。

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

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

简单。自我解释。

在版本3.36.0 11/20/21上进行测试。

CREATE TEMP TABLE x (col1 TEXT, col2 TEXT, col3 TEXT);

INSERT INTO x 
VALUES 
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc');

SELECT * FROM x;

输出:

col1|col2|col3|
----+----+----+
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |

版本检查:

SELECT sqlite_version();

输出:

sqlite_version()|
----------------+
3.36.0          |

有些人可能会说-所有的“..”的答案已经过时了;尽管如此,它们还是非常有用的。有时候,我们都坐在桌子上“过去的爆炸”,然后15年前的纸条拯救了我们的一天。

Fearless_fool对于旧版本有一个很好的答案。我只是想补充一下,你需要确保你列出了所有的列。如果你有3列,你需要确保select作用在3列上。

示例:我有3列,但我只想插入2列的数据。假设我不关心第一列因为它是一个标准整数id。我可以这样做……

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…”“工会”的声明将失去秩序。(从AG1)