关于sql server:如何在不重复语句的“INSERT INTO dbo.Blah”部分的情况下插入多行?

How do I insert multiple rows WITHOUT repeating the “INSERT INTO dbo.Blah” part of the statement?

我知道我在几年前就做过这个,但是我记不清语法了,而且我在任何地方都找不到它,因为我有很多关于"批量导入"的帮助文档和文章。

这是我想做的,但语法不完全正确…拜托,以前做过这件事的人,帮帮我:)

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

我知道这接近正确的语法。我可能需要"散装"这个词,或者别的,我记不起来了。有什么想法吗?

我需要这个用于SQL Server 2005数据库。我试过这个代码,但没有用:

1
2
3
4
5
6
7
8
9
10
11
12
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'.


您的语法几乎在SQL Server 2008中可用(但在SQL Server 20051中不适用):

1
2
3
4
5
6
7
8
9
10
11
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。我把这个答案留在这里,因为我相信它仍然是相关的。


1
2
3
4
5
6
INSERT INTO dbo.MyTable (ID, Name)
SELECT 123, 'Timmy'
UNION ALL
SELECT 124, 'Jonny'
UNION ALL
SELECT 125, 'Sally'

对于SQL Server 2008,可以根据问题中的语句在一个VALUES子句中执行该操作(只需添加逗号来分隔每个VALUES语句)。


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

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

如果需要对数据进行硬编码,那么SQL 2008和更高版本允许您执行以下操作…

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

使用INSERT INTO ... VALUES语法,就像DanielVassallo的答案一样有一个令人讨厌的限制:

From MSDN

The maximum number of rows that can be constructed by inserting rows directly in the VALUES list is 1000

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

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

OCx1〔4〕

这将从SQL Server 2008开始工作+


你可以这样做(难看但有效):

1
2
3
4
5
6
7
8
9
10
INSERT INTO dbo.MyTable (ID, Name)
select * from
(
 select 123, 'Timmy'
  union all
 select 124, 'Jonny'
  union all
 select 125, 'Sally'
 ...
) x

可以使用联合:

1
2
3
4
5
6
7
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)


我一直在使用以下功能:

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

它将为id和name添加10行具有唯一guid的内容。

注意:不要以";"结束最后一行(go 10),因为它将引发错误:发生了致命的脚本错误。分析go时遇到语法错误。


1
2
3
4
5
6
7
8
9
10
11
12
13
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

或者你可以用另一种方式

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

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

查看完整的文章和代码解释,请访问http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

将以下代码复制到SQL Server中以查看示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)

对于SQL Server 2008,这看起来还可以。对于SS2005和更早的版本,需要重复values语句。

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

编辑:我的坏。您必须为SS2005中的每一行重复"插入到"。

1
2
3
4
5
6
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')

这将实现您所要求的:

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

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

1
2
3
4
5
INSERT INTO table1 (ID, Name)
    SELECT
         ID,
         Name
    FROM table2

甚至从多个表:

1
2
3
4
5
6
7
INSERT INTO table1 (column2, column3)
    SELECT
         t2.column,
         t3.column
    FROM table2 t2
         INNER JOIN table3 t3
         ON t2.ID = t3.ID


对应于insert(transact-sql)(SQL Server 2005),不能省略INSERT INTO dbo.Blah,每次都必须指定它,或者使用其他语法/方法,


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

1
2
3
4
5
6
CREATE TABLE [dbo].[Sample](
[a] [int] NULL,
[b] [int] NULL,
[c] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[D] [int] NULL
)

因此,在不重复INSERT语句的情况下,不能使用以下查询在该表中插入多个记录,

1
2
3
4
5
6
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)

同样,使用SqlBulkCopy bulkcopy = new SqlBulkCopy(con)的c

一次可以插入10行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   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();
        }