ステートメントの「INSERT INTO…」の部分を繰り返さずに複数の行を挿入しますか?


536

私は数年前にこれを行ったことを知っていますが、構文を思い出せず、大量のヘルプドキュメントや「バルクインポート」に関する記事が表示されるため、どこにあるかわかりません。

これが私がしたいことですが、構文は正確ではありません...以前にこれを行ったことがある人、私を助けてください:)

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'.


4
上記のコードは、valuesステートメントの後に '、'を追加するだけで結構です
sam

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

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.クリスコンプトン

回答:


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

SQL Server 2008では、質問のステートメントとまったく同じように1 つのVALUES句でそれを行うことができます(各値ステートメントを区切るためにカンマを追加する必要があるだけです)...


10
これは複数のINSERTステートメントを使用するよりも効率的ですか?
コードコマンダー

7
@Code Commander:いいえ、コンパイルするのに時間がかかります。はい、挿入は1つだけです。しかし、それは質問に答えます:繰り返しはありませんINSERT table (columnlist)
gbn '25年

3
@VoidKing半年後のことだと思いますが、ずっと前にこれを理解しているかもしれませんが、非常に簡単です。を使用しselectて、列と行のセットを作成し、設計により、これらの行をinsert同じ数の列を持つ別のテーブルに編集できます。リテラルと値を組み合わせて使用​​することもできます。たとえば、insertwith select 'A', ID from ATableを使用すると、毎回最初の列に「A」が挿入され、2番目の列にATableの対応する行のID列の値が挿入されます。
MarioDS 2014

1
これはDB2でも機能します。DB2は、時代遅れのテクノロジーに夢中になっている私たちにとって重要な補足です。カンマで区切られた値は、SQL Server 2008以降で作業している人にとってはより良いと思います。OPは、最初の値を除くすべての「値」を削除し、aに置き換えることができます
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 2013

27
Server 2008では、この方法で挿入される行は1000行を超えることができません。
マイケル-クレイシャーキーはどこですか

1
1つの値セットに欠陥があるとどうなりますか?すべての挿入はロールバックされますか、それとも障害のある行だけですか?
netblognet 2016

2
@netblognet私は唯一の障害のある行が(正しく挿入されている他のすべてのすべて)が挿入されていないことをテスト
マウリシオ・グラシアグティエレス

1
@Michael持ち上げられる可能性があるstackoverflow.com/a/42703601/5070879
Lukasz Szozda

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

Daniel Vassalloの回答のINSERT INTO ... VALUESような構文を使用すると、迷惑な制限が1つあります。

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 2017年

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

3
この回答の利点は、同じ値を繰り返さずに指定する方法を提供することです(これは私が探していたものです)。たとえば、同一の3番目の列があれば、1000回繰り返す必要はありません。
Vadim Berman

1
@VadimBermanはい、これはテーブルにデフォルトが定義されていない場合の良いシナリオです。
Lukasz Szozda、2018年

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サーバーにコピーして、サンプルを表示します。

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を含む10行が追加されます。

注:最後の行(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による複数行の挿入

マルチテーブル挿入では、サブクエリの評価から返された行から派生した計算された行を1つ以上のテーブルに挿入します。

無条件の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を1回実行します。

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に任せください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.