【问题标题】:Insert multiple rows WITHOUT repeating the "INSERT INTO ..." part of the statement?插入多行而不重复语句的“INSERT INTO ...”部分?
【发布时间】:2011-02-07 03:47:24
【问题描述】:

我知道几年前我已经这样做了,但我不记得语法了,而且由于查阅了大量关于“批量导入”的帮助文档和文章,我无法在任何地方找到它。

这是我想要做的,但语法不完全正确......请以前做过这个的人帮帮我:)

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

我知道这是接近正确的语法。我可能需要在其中使用“BULK”这个词,或者其他什么,我不记得了。有什么想法吗?

我需要这个用于 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'.

【问题讨论】:

  • 你上面的代码没问题,只需要在values语句后添加','
  • INSERT INTO @blah (ID, Name), VALUES (123, 'Timmy'), VALUES (124, 'Jonny'), VALUES (125, 'Sally')
  • 请注意:您最多只能通过此方法插入 1000 行。插入#Test (LWPurchaseOrderID)VALUES (935791), (935933)
  • 2005 不再受支持。对于 2008、2012 和 2016,您可以几乎使用您输入的内容INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') “VALUES”只出现一次,并且您需要在集合之间使用逗号。

标签: sql-server tsql sql-server-2005 insert


【解决方案1】:

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

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
  • Server 2008 不允许以这种方式插入超过 1000 行。
  • 如果一个值集有问题怎么办?是所有插入回滚还是只回滚错误行?
  • @netblognet 我刚刚测试了只有错误的行没有插入(所有其他的都正确插入)
【解决方案2】:
INSERT INTO dbo.MyTable (ID, Name)
SELECT 123, 'Timmy'
UNION ALL
SELECT 124, 'Jonny'
UNION ALL
SELECT 125, 'Sally'

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

【讨论】:

  • 这是否比使用多个 INSERT 语句更有效?
  • @Code Commander:不,编译时间更长。是的,因为您只有一个插件。但它回答了这个问题:INSERT table (columnlist) 不再重复
  • @VoidKing 我知道这是半年之后的事情,你可能很久以前就知道了,但这真的很简单。通过使用select,您可以创建一个包含列和行的集合,并且通过设计,这些行可以inserted 到另一个具有相同数量列的表中。您甚至可以混合使用文字和值。比如insertselect 'A', ID from ATable一起使用,每次都会在第一列插入'A',在第二列插入ATable对应行的ID列值。
  • 这也适用于 DB2,对于我们这些陷入过时技术的人来说,这是一个重要的旁注。对于那些在 SQL Server 2008 或更高版本中工作的人,我认为用逗号分隔的值更好。 OP 可以删除除第一个之外的所有“值”并替换为 ,
  • @PRMan 在 SQL Server 2008 版本之后您不会这样做。如上所述...
【解决方案3】:

如果您的数据已经在您的数据库中,您可以这样做:

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)

【讨论】:

    【解决方案4】:

    使用INSERT INTO ... VALUES 语法,如Daniel Vassallo's 答案 有一个烦人的限制:

    来自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+ 开始工作

    【讨论】:

    • 我可以有一篇关于这种“子”语法的文章的链接吗?
    • @CodeCamper docs.microsoft.com/en-us/sql/t-sql/queries/… 部分:C. Specifying multiple values as a derived table in a FROM clause
    • 这个答案的优点是它提供了一种指定相同值而不重复它们的方法(这是我一直在寻找的)。例如。使用相同的第三列,您无需重复一千次。
    • @VadimBerman 是的,当表上没有定义默认值时,这是一个很好的场景。
    【解决方案5】:

    你可以这样做(丑陋但有效):

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

    【讨论】:

      【解决方案6】:

      这将实现您的要求:

      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
      

      【讨论】:

        【解决方案7】:

        你可以使用联合:

        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)
        

        【讨论】:

          【解决方案8】:

          这对于 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')  
          

          【讨论】:

            【解决方案9】:

            在 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)
            

            【讨论】:

              【解决方案10】:
              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)
              

              【讨论】:

                【解决方案11】:

                我一直在使用以下:

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

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

                注意:不要以';'结束最后一行(GO 10)因为它会抛出错误:发生了致命的脚本错误。解析 GO 时遇到语法错误。

                【讨论】:

                  【解决方案12】:

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

                  【讨论】:

                    【解决方案13】:

                    这在 SQL 中工作得非常快,而且效率很高。 假设你有表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();
                            }
                    

                    【讨论】:

                      【解决方案14】:

                      PostgreSQL中,你可以这样做;

                      2 列表的通用示例;

                      INSERT INTO <table_name_here>
                          (<column_1>, <column_2>)
                      VALUES
                          (<column_1_value>, <column_2_value>),
                          (<column_1_value>, <column_2_value>),
                          (<column_1_value>, <column_2_value>),
                          ...
                          (<column_1_value>, <column_2_value>);
                      

                      在此处查看真实世界的示例;

                      A - 创建表

                      CREATE TABLE Worker
                      (
                          id serial primary key,
                          code varchar(256) null,
                          message text null
                      );
                      

                      B - 插入批量值

                      INSERT INTO Worker
                          (code, message)
                      VALUES
                          ('a1', 'this is the first message'),
                          ('a2', 'this is the second message'),
                          ('a3', 'this is the third message'),
                          ('a4', 'this is the fourth message'),
                          ('a5', 'this is the fifth message'),
                          ('a6', 'this is the sixth message');
                      

                      【讨论】:

                        【解决方案15】:

                        Oracle SQL Server Insert Multiple Rows

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

                        无条件 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 数据库对子查询返回的每一行执行每个 insert_into_clause 一次。

                        MySQL Server Insert Multiple Rows

                        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);
                        

                        【讨论】:

                          【解决方案16】:

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

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

                          -- 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 为您决定这些东西。

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2018-08-18
                            • 1970-01-01
                            • 2020-03-26
                            • 1970-01-01
                            • 2014-09-01
                            • 2017-04-21
                            相关资源
                            最近更新 更多