在单个SQL查询中插入多行?

2000

我有多组数据需要一次性插入,比如4行。我的表有三列:PersonIdOffice

INSERT INTO MyTable VALUES ("John", 123, "Lloyds Office");
INSERT INTO MyTable VALUES ("Jane", 124, "Lloyds Office");
INSERT INTO MyTable VALUES ("Billy", 125, "London Office");
INSERT INTO MyTable VALUES ("Miranda", 126, "Bristol Office");

我能否在一条SQL语句中插入所有4行数据?


10
主持人提示: 请将有关此问题的讨论全部转到此元帖 - George Stocker
4
有关 Oracle SQL,请参阅 https://dev59.com/lXVD5IYBdhLWcg3wQJOT#93724。 - ono2012
1
@Chinggis6 是的,这很容易实现,只需使用 select 语句选择列值即可: - Kzqai
2
@Chinggis6 插入到个人资料(名称,描述)中选择第一个用户和“自动生成”的内容 你似乎混淆了插入语句和更新语句,它们是不同的东西。 - Kzqai
1
@Chinggis6 哦,我明白了。我建议使用标准的insert ... select语法,它可以满足你的所有需求,并且非常灵活。https://dev.mysql.com/doc/refman/5.5/en/insert.html - Kzqai
显示剩余9条评论
4个回答

2649

在SQL Server 2008中,你可以使用单个SQL INSERT语句插入多行。

INSERT INTO MyTable ( Column1, Column2 ) VALUES
( Value1, Value2 ), ( Value1, Value2 )

参考 MOC 课程 2778A - 在 SQL Server 2008 中编写 SQL 查询。

例如:

INSERT INTO MyTable
  ( Column1, Column2, Column3 )
VALUES
  ('John', 123, 'Lloyds Office'), 
  ('Jane', 124, 'Lloyds Office'), 
  ('Billy', 125, 'London Office'),
  ('Miranda', 126, 'Bristol Office');

433
请注意,一个插入语句中最多可以有1000行数据。 - cryss
219
应该这样表达:“一个VALUES子句中的最大行数为1000”。限制的不是INSERT语句,而是VALUES子句。 - Anon
41
我知道这个问题和答案很旧,但我想提一下,在使用问题中提到的方法和这个答案中提到的方法之间存在功能差异。第一个方法会在插入表中有1条记录时执行X次触发器。而第二个方法会在插入表中有x条记录时执行1次触发器。假设您已经正确地将触发器与批量插入配合使用,那么第二种方法是性能最佳的选择。 - Edwin Stoteler
8
这在 SQL Server 2005 上不起作用,请参见 https://dev59.com/G3E85IYBdhLWcg3wwWat。 - pkr
5
在 T-SQL 中,分号通常是可选的,但据报道未来可能会要求使用它们。你应该养成在每个语句末尾使用分号来终止的习惯--这样你的代码看起来更漂亮,我认为。 - NReilingh
显示剩余9条评论

883

如果您要插入到单个表中,您可以像这样编写查询语句(可能仅适用于MySQL):

INSERT INTO table1 (First, Last)
VALUES
    ('Fred', 'Smith'),
    ('John', 'Smith'),
    ('Michael', 'Smith'),
    ('Robert', 'Smith');

60
从 SQL Server 2008 开始,如果你将双引号替换为单引号,这段代码就能够运行。 - Valentino Vranken
21
也适用于PostgreSQL v9.0。 - suspectus
13
而且还有SQLite。 - Michał Klimczak
7
只有从SQLite 3.7.11版本开始才支持此功能。如果无法保证,请使用此处展示的UNION方法:https://dev59.com/w3I-5IYBdhLWcg3w6tJR#5009740 - Darren Cook
5
Muneem,每个INSERT语句的限制是1,000行VALUE。 - John Pittaway
显示剩余5条评论

157

注意: 此答案适用于SQL Server 2005。对于SQL Server 2008及更高版本,其他回答中提供了更好的方法。

您可以使用INSERT加SELECT UNION ALL

INSERT INTO MyTable  (FirstCol, SecondCol)
    SELECT  'First' ,1
    UNION ALL
SELECT  'Second' ,2
    UNION ALL
SELECT  'Third' ,3
...

只适用于小数据集,对于你的4条记录应该可以。


第一次就成功了,谢谢!我甚至可以添加额外的内容,比如:'Before date: ' + date2str(GETDATE()) + ' after date.' 我知道date2str是一个有点奇怪的命令,但它是我数据库中的特殊语法。 - Michael Larsson
从Oracle 23c版本开始,Oracle现在也支持值构造函数。 - Vijay Balebail

92

INSERT语句使用VALUES语法可以插入多行。为此,请包括多个列值列表,每个列表用括号括起来并用逗号分隔。

示例:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

3
更好的问题是,你为什么想这样做?为什么不把清洁工具的4个命令一起运行在一个批处理中呢?如果其中一个行失败了,整个批处理就会失败。如果你把它们分开成组依次执行,可能会有3个成功,而只有1个失败。 - M T Head
13
@m-t-head,我有一个例子说明我为什么想这样做,并将给出两个原因。我正在向一个具有数据完整性检查触发器的表中插入数据。原因1:分别插入值会违反完整性检查,从而撤销事务并返回错误。我正在使用SQL Server,它不支持延迟约束,因此即使不是触发器而是常规约束,它也无法工作。原因2:完整性检查是一项昂贵的过程,我宁愿在每个事务中执行一次,而不是执行成千上万次。我仍在寻找解决方案。 - tomosius
1
你可以创建一个CTE,并使用insert into YourTable (ID,Name)从select ID,Name From CTE插入数据。 - Mohammad Farahani
这个问题怎么样?https://stackoverflow.com/questions/51763204/sql-inserting-multiple-records-updates-existing-in-single-query 基本上是同样的问题,但具有在重复记录的情况下更新的功能。 - DayIsGreen
3
主要原因是性能。将成千上万行数据捆绑成合理大小的批次,并使用每批次一个单独的INSERT语句,可以使插入操作更快。 - uncoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接