插入多行而不重复语句的“ INSERT INTO…”部分?


536

我知道我早在几年前就完成了此操作,但是我不记得该语法,而且由于收集了大量有关“批量导入”的帮助文档和文章,所以在任何地方都找不到它。

这是我想做的,但是语法不完全正确……请曾经做过此事的人帮帮我:)

INSERT INTO dbo.MyTable (ID, Name)
VALUES (123, 'Timmy'),
    (124, 'Jonny'),
    (125, 'Sally')

我知道这接近正确的语法。我可能在其中需要“散装”一词,或者我不记得的东西。任何的想法?

我需要一个SQL Server 2005数据库。我已经尝试过此代码,但无济于事:

DECLARE @blah TABLE
(
    ID INT NOT NULL PRIMARY KEY,
    Name VARCHAR(100) NOT NULL
)

INSERT INTO @blah (ID, Name)
    VALUES (123, 'Timmy')
    VALUES (124, 'Jonny')
    VALUES (125, 'Sally')

SELECT * FROM @blah

我越来越 Incorrect syntax near the keyword 'VALUES'.


4
您的上述代码很好,只需要在values语句后添加“,”
sam,2015年

4
插入@blah(ID,名称),值(123,“ Timmy”),值(124,“ Jonny”),值(125,“ Sally”)
sam 2015年

1
请注意:此方法最多只能插入1000行。INSERT INTO #Test(LWPurchaseOrderID)VALUES(935791),(935933)
Anoop Verma

16
不再支持2005。对于2008年,2012年和2016年,您几乎可以使用您放置的内容INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') “ VALUES”仅出现一次,并且在集合之间需要逗号。
J. Chris Compton

Answers:


328
INSERT INTO dbo.MyTable (ID, Name)
SELECT 123, 'Timmy'
UNION ALL
SELECT 124, 'Jonny'
UNION ALL
SELECT 125, 'Sally'

对于SQL Server 2008,可以完全按照问题中的语句在一个VALUES子句中执行此操作(您只需要添加一个逗号来分隔每个values语句)...


10
这比使用多个INSERT语句更有效吗?
代码指挥官

7
@Code Commander:不,因为它的编译时间更长。是的,因为您只有一个插入物。但是它回答了问题:没有重复INSERT table (columnlist)
gbn

3
@VoidKing我知道这是半年之后,您可能很久以前就已经知道了,但这确实非常简单。通过使用select创建具有列和行的集合,并通过设计,可以将这些行insert编入到具有相等列数的另一个表中。您甚至可以混合使用文字和值。例如,使用insertwith select 'A', ID from ATable将每次在第一列中插入“ A”,并在第二列中插入ATable对应行的ID列值。
MarioDS 2014年

1
这对DB2也适用,对于那些被过时技术困扰的人来说,DB2是一个重要的说明。对于那些在SQL Server 2008或更高版本中工作的人,用逗号分隔的值在我看来更好。OP可以删除除第一个值以外的所有“值”,并替换为
JPK

1
@PRMan您不会在SQL Server 2008版本之后执行此操作。如上所述...
gbn

510

您的语法几乎可以在SQL Server 2008中使用(但不能在SQL Server 2005 1中使用):

CREATE TABLE MyTable (id int, name char(10));

INSERT INTO MyTable (id, name) VALUES (1, 'Bob'), (2, 'Peter'), (3, 'Joe');

SELECT * FROM MyTable;

id |  name
---+---------
1  |  Bob       
2  |  Peter     
3  |  Joe       

1当回答问题时,并没有明显地表明该问题是针对SQL Server 2005的。我在此保留此答案,因为我认为它仍然很重要。


在SQL Server 2012中工作
user2601995

27
Server 2008不允许以这种方式插入超过1000行。
Michael-Clay Shirky在哪里,2013年

1
如果一个值集有问题怎么办?所有插页会回滚还是仅出现故障行?
netblognet

2
@netblognet我刚刚测试了没有插入错误的行(所有其他所有行都正确插入了)
Mauricio Gracia Gutierrez


243

如果数据已经在数据库中,则可以执行以下操作:

INSERT INTO MyTable(ID, Name)
SELECT ID, NAME FROM OtherTable

如果您需要对数据进行硬编码,则可以使用SQL 2008和更高版本执行以下操作...

INSERT INTO MyTable (Name, ID)
VALUES ('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)

28

使用INSERT INTO ... VALUES类似于Daniel Vassallo的答案的语法,存在一个令人讨厌的限制:

MSDN

通过直接在VALUES列表中插入行可以构造的最大行数为1000

忽略此限制的最简单方法是使用派生表,例如:

INSERT INTO dbo.Mytable(ID, Name)
SELECT ID, Name 
FROM (
   VALUES (1, 'a'),
          (2, 'b'),
          --...
          -- more than 1000 rows
)sub (ID, Name);

LiveDemo


此功能将从SQL Server 2008+开始


我可以链接到有关此“ sub”语法的文章吗?
CodeCamper

2
@CodeCamperdocs.microsoft.com/ zhC. Specifying multiple values as a derived table in a FROM clause
Lukasz Szozda

3
该答案的优点在于,它提供了一种无需重复就可以指定相同值的方法(这正是我所寻找的)。例如,如果第三列相同,则无需重复一千次。
瓦迪姆·伯曼

1
@VadimBerman是的,当表上未定义默认值时,这是一个好方案。
Lukasz Szozda

14

您可以执行此操作(难看但可行):

INSERT INTO dbo.MyTable (ID, Name) 
select * from
(
 select 123, 'Timmy'
  union all
 select 124, 'Jonny' 
  union all
 select 125, 'Sally'
 ...
) x

10

这将实现您所要求的:

INSERT INTO table1 (ID, Name)
    VALUES (123, 'Timmy'), 
           (124, 'Jonny'), 
           (125, 'Sally');

对于将来的开发人员,您还可以从另一个表插入

INSERT INTO table1 (ID, Name)
    SELECT 
         ID, 
         Name 
    FROM table2

甚至从多个表

INSERT INTO table1 (column2, column3)
    SELECT 
         t2.column, 
         t3.column
    FROM table2 t2
         INNER JOIN table3 t3
         ON t2.ID = t3.ID

8

您可以使用联合:

INSERT INTO dbo.MyTable (ID, Name) 
SELECT ID, Name FROM (
    SELECT 123, 'Timmy'
    UNION ALL
    SELECT 124, 'Jonny'
    UNION ALL
    SELECT 125, 'Sally'
) AS X (ID, Name)

6

对于SQL Server 2008,这看起来不错。对于SS2005及更早版本,您需要重复VALUES语句。

INSERT INTO dbo.MyTable (ID, Name)  
VALUES (123, 'Timmy')  
VALUES (124, 'Jonny')   
VALUES (125, 'Sally')  

编辑::我的坏。您必须为SS2005中的每一行重复“ INSERT INTO”。

INSERT INTO dbo.MyTable (ID, Name)  
VALUES (123, 'Timmy')  
INSERT INTO dbo.MyTable (ID, Name)  
VALUES (124, 'Jonny')   
INSERT INTO dbo.MyTable (ID, Name)  
VALUES (125, 'Sally')  

6

在SQL Server中使用XML插入多行会更容易,否则将变得非常乏味。

在此处查看带有代码说明的完整文章,网址为http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

将以下代码复制到sql server中以查看示例。

declare @test nvarchar(max)

set @test = '<topic><dialog id="1" answerId="41">
        <comment>comment 1</comment>
        </dialog>
    <dialog id="2" answerId="42" >
    <comment>comment 2</comment>
        </dialog>
    <dialog id="3" answerId="43" >
    <comment>comment 3</comment>
        </dialog>
    </topic>'

declare @testxml xml
set @testxml = cast(@test as xml)
declare @answerTemp Table(dialogid int, answerid int, comment varchar(1000))

insert @answerTemp
SELECT  ParamValues.ID.value('@id','int') ,
ParamValues.ID.value('@answerId','int') ,
ParamValues.ID.value('(comment)[1]','VARCHAR(1000)')
FROM @testxml.nodes('topic/dialog') as ParamValues(ID)

6
USE YourDB
GO
INSERT INTO MyTable (FirstCol, SecondCol)
SELECT 'First' ,1
UNION ALL
SELECT 'Second' ,2
UNION ALL
SELECT 'Third' ,3
UNION ALL
SELECT 'Fourth' ,4
UNION ALL
SELECT 'Fifth' ,5
GO

或者您可以使用其他方式

INSERT INTO MyTable (FirstCol, SecondCol)
VALUES 
('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)

6

我一直在使用以下内容:

INSERT INTO [TableName] (ID, Name)
values (NEWID(), NEWID())
GO 10

它将添加十行,其ID和名称具有唯一的GUID。

注意:请勿在最后一行(GO 10)后面加';' 因为它将引发错误:发生致命的脚本错误。解析GO时遇到语法错误。



2

这在SQL中非常快速且高效地工作。假设您有Table Sample with 4 column a,b,c,d where a,b,d are int and c column is Varchar(50)

CREATE TABLE [dbo].[Sample](
[a] [int] NULL,
[b] [int] NULL,
[c] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[D] [int] NULL
)

因此,您不能使用以下查询在此表中插入多个记录,而无需重复插入语句,

DECLARE @LIST VARCHAR(MAX)
SET @LIST='SELECT 1, 1, ''Charan Ghate'',11
     SELECT 2,2, ''Mahesh More'',12
     SELECT 3,3,''Mahesh Nikam'',13
     SELECT 4,4, ''Jay Kadam'',14'
INSERT SAMPLE (a, b, c,d) EXEC(@LIST)

也与C#使用 SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

您一次可以插入10行

   DataTable dt = new DataTable();
        dt.Columns.Add("a");
        dt.Columns.Add("b");
        dt.Columns.Add("c");
        dt.Columns.Add("d");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dt.NewRow();
            dr["a"] = 1;
            dr["b"] = 2;
            dr["c"] = "Charan";
            dr["d"] = 4;
            dt.Rows.Add(dr);
        }
        SqlConnection con = new SqlConnection("Connection String");
        using (SqlBulkCopy bulkcopy = new SqlBulkCopy(con))
        {
            con.Open();
            bulkcopy.DestinationTableName = "Sample";
            bulkcopy.WriteToServer(dt);
            con.Close();
        }

0

Oracle SQL Server插入多行

在多表插入中,您将从子查询的评估返回的行中得出的计算行插入一个或多个表中。

无条件INSERT ALL:-要一次向一个表中添加多行,请使用以下形式的INSERT语句:

INSERT ALL
   INTO table_name (column_list) VALUES (value_list_1)
   INTO table_name (column_list) VALUES (value_list_2)
   INTO table_name (column_list) VALUES (value_list_3)
   ...
   INTO table_name (column_list) VALUES (value_list_n)
SELECT 1 FROM DUAL; -- SubQuery

指定ALL后跟多个insert_into_clauses来执行无条件多表插入。Oracle Database对子查询返回的每一行执行一次每个insert_into_clause。

MySQL服务器插入多行

INSERT INTO table_name (column_list)
VALUES
    (value_list_1),
    (value_list_2),
    ...
    (value_list_n);

单行插入查询

INSERT INTO table_name (col1,col2) VALUES(val1,val2);

0

这里的其他人建议了几种多记录语法。对此进行说明,我建议您首先插入一个临时表,然后从那里插入主表。

这样做的原因是从查询中加载数据可能会花费更长的时间,并且最终锁定表或页面的时间可能会比所需时间更长,这会减慢针对该表运行的其他查询的速度。

-- Make a temp table with the needed columns
select top 0 *
into #temp
from MyTable (nolock)

-- load data into it at your leisure (nobody else is waiting for this table or these pages)
insert #temp (ID, Name)
values (123, 'Timmy'),
(124, 'Jonny'),
(125, 'Sally')

-- Now that all the data is in SQL, copy it over to the real table. This runs much faster in most cases.
insert MyTable (ID, Name)
select ID, Name
from #temp

-- cleanup
drop table #temp

同样,在大多数情况下,您的ID可能应该为identity(1,1),并且您不应该插入它们。让SQL 您决定这些东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.