Mehrere Zeilen einfügen, OHNE den Teil "INSERT INTO ..." der Anweisung zu wiederholen?

536

Ich weiß, dass ich das vor Jahren getan habe, aber ich kann mich nicht an die Syntax erinnern, und ich kann sie nirgendwo finden, weil ich unzählige Hilfedokumente und Artikel über "Massenimporte" abgerufen habe.

Folgendes möchte ich tun, aber die Syntax stimmt nicht genau ... bitte, jemand, der dies bereits getan hat, hilft mir :)

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

Ich weiß, dass dies nahe an der richtigen Syntax liegt. Ich brauche vielleicht das Wort "BULK" oder etwas, an das ich mich nicht erinnern kann. Irgendeine Idee?

Ich benötige dies für eine SQL Server 2005-Datenbank. Ich habe diesen Code ohne Erfolg ausprobiert:

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

Ich erhalte Incorrect syntax near the keyword 'VALUES'.

Timothy Khouri
quelle
4
Ihr obiger Code ist in Ordnung, Sie müssen nur ',' nach der
Werteanweisung
4
INSERT INTO @blah (ID, Name), VALUES (123, 'Timmy'), VALUES (124, 'Jonny'), VALUES (125, 'Sally')
sam
1
Nur zur Vorsicht: Mit dieser Methode können Sie nur bis zu 1000 Zeilen einfügen. INSERT IN #Test (LWPurchaseOrderID) VALUES (935791), (935933)
Anoop Verma
16
2005 wird nicht mehr unterstützt. Für 2008, 2012 und 2016 können Sie fast das verwenden, was Sie INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') eingeben. "VALUES" wird nur einmal angezeigt und Sie benötigen Kommas zwischen den Sätzen.
J. Chris Compton

Antworten:

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

Kann dies für SQL Server 2008 in einer VALUES-Klausel genau gemäß der Anweisung in Ihrer Frage tun (Sie müssen nur ein Komma hinzufügen, um jede Werteanweisung zu trennen) ...

gbn
quelle
10
Ist dies effizienter als die Verwendung mehrerer INSERT-Anweisungen?
Code Commander
7
@ Code Commander: Nein, da das Kompilieren länger dauert. Ja, Sie haben nur einen Einsatz. Aber es beantwortet die Frage: keine Wiederholung desINSERT table (columnlist)
gbn
3
@VoidKing Ich weiß, dass dies ein halbes Jahr später kommt und Sie haben das vielleicht schon vor langer Zeit herausgefunden, aber es ist wirklich ganz einfach. Durch die Verwendung selecterstellen Sie eine Menge mit Spalten und Zeilen, und durch das Design können diese Zeilen seininsert in eine andere Tabelle mit der gleichen Anzahl von Spalten umgewandelt werden. Sie können sogar eine Mischung aus Literalen und Werten verwenden. Wenn Sie beispielsweise insertwith verwenden, wird select 'A', ID from ATablejedes Mal 'A' in die erste Spalte und der ID-Spaltenwert der entsprechenden Zeile von ATable in die zweite Spalte eingefügt.
MarioDS
1
Dies funktioniert auch mit DB2, was eine wichtige Nebenbemerkung für diejenigen von uns ist, die in veralteter Technologie stecken. Die durch Kommaantwort getrennten Werte sind meiner Meinung nach besser für diejenigen unter Ihnen, die in SQL Server 2008 oder höher arbeiten. Das OP kann alle "Werte" außer dem ersten entfernen und durch ein,
JPK
1
@PRMan würden Sie das nach der Version SQL Server 2008 nicht tun. Wie erwähnt ...
gbn
510

Ihre Syntax funktioniert fast in SQL Server 2008 (jedoch nicht in 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 Als die Frage beantwortet wurde, wurde nicht klargestellt, dass sich die Frage auf SQL Server 2005 bezieht. Ich lasse diese Antwort hier, da ich glaube, dass sie immer noch relevant ist.

Daniel Vassallo
quelle
Funktioniert in SQL Server 2012
user2601995
27
Auf Server 2008 können nicht mehr als 1000 Zeilen auf diese Weise eingefügt werden.
Michael - Wo ist Clay Shirky
1
Was passiert, wenn ein Wertesatz fehlerhaft ist? Werden alle Einsätze zurückgerollt oder nur die fehlerhafte Reihe?
Netblognet
2
@netblognet Ich habe gerade getestet, dass nur fehlerhafte Zeilen nicht eingefügt werden (alle anderen sind korrekt eingefügt)
Mauricio Gracia Gutierrez
1
@ Michael Es könnte Stackoverflow.com/a/42703601/5070879
Lukasz Szozda
243

Wenn sich Ihre Daten bereits in Ihrer Datenbank befinden, können Sie Folgendes tun:

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

Wenn Sie die Daten hart codieren müssen, können Sie mit SQL 2008 und späteren Versionen Folgendes tun ...

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

Bei Verwendung der INSERT INTO ... VALUESSyntax wie in Daniel Vassallos Antwort gibt es eine ärgerliche Einschränkung:

Von MSDN

Die maximale Anzahl von Zeilen, die durch Einfügen von Zeilen direkt in die VALUES-Liste erstellt werden können, beträgt 1000

Der einfachste Weg, diese Einschränkung zu umgehen, ist die Verwendung abgeleiteter Tabellen wie:

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

LiveDemo


Dies funktioniert ab SQL Server 2008+

Lukasz Szozda
quelle
Kann ich einen Link zu einem Artikel über diese 'Sub'-Syntax haben?
CodeCamper
2
@ CodeCamper docs.microsoft.com/en-us/sql/t-sql/queries/… Abschnitt:C. Specifying multiple values as a derived table in a FROM clause
Lukasz Szozda
3
Der Vorteil dieser Antwort ist, dass sie eine Möglichkeit bietet, identische Werte anzugeben, ohne sie zu wiederholen (wonach ich gesucht habe). Zum Beispiel mit einer dritten Spalte, die identisch ist, müssten Sie sie nicht tausendmal wiederholen.
Vadim Berman
1
@VadimBerman Ja, das ist ein gutes Szenario, wenn in der Tabelle kein Standard definiert ist.
Lukasz Szozda
14

Sie könnten dies tun (hässlich, aber es funktioniert):

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

Damit erreichen Sie, wonach Sie fragen:

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

Für zukünftige Entwickler können Sie auch aus einer anderen Tabelle einfügen :

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

Oder sogar aus mehreren Tabellen :

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

Sie können eine Gewerkschaft verwenden:

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)
Cade Roux
quelle
6

Dies sieht für SQL Server 2008 in Ordnung aus. Für SS2005 und früher müssen Sie die Anweisung VALUES wiederholen.

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

EDIT :: Mein schlechtes. Sie müssen das 'INSERT INTO' für jede Zeile in SS2005 wiederholen.

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')  
DaveE
quelle
6

Es wäre einfacher, XML in SQL Server zum Einfügen mehrerer Zeilen zu verwenden, da dies sonst sehr mühsam wird.

Den vollständigen Artikel mit Code-Erklärungen finden Sie hier http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

Kopieren Sie den folgenden Code in den SQL Server, um ein Beispiel anzuzeigen.

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)
Joe
quelle
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

ODER SIE KÖNNEN EINEN ANDEREN WEG VERWENDEN

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

Ich habe Folgendes verwendet:

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

Es werden zehn Zeilen mit eindeutigen GUIDs für ID und Name hinzugefügt.

Hinweis: Beenden Sie die letzte Zeile (GO 10) nicht mit ';' weil es einen Fehler auslöst: Ein schwerwiegender Skriptfehler ist aufgetreten. Beim Parsen von GO ist eine falsche Syntax aufgetreten.

valentinvs
quelle
5

Entsprechend INSERT (Transact-SQL) (SQL Server 2005) können Sie es nicht auslassen INSERT INTO dbo.Blahund müssen es jedes Mal angeben oder eine andere Syntax / einen anderen Ansatz verwenden.

abatishchev
quelle
2

Dies funktioniert sehr schnell und effizient in SQL. Angenommen, Sie haben eine Tabelle 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
)

Sie können also nicht mehrere Datensätze in diese Tabelle mit der folgenden Abfrage einfügen, ohne die Anweisung insert zu wiederholen.

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)

Auch mit C # mit SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

Sie können 10 Zeilen gleichzeitig einfügen

   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();
        }
Charan Ghate
quelle
0

Oracle SQL Server Mehrere Zeilen einfügen

In einer multitablen Einfügung fügen Sie berechnete Zeilen, die aus den von der Auswertung einer Unterabfrage zurückgegebenen Zeilen abgeleitet wurden, in eine oder mehrere Tabellen ein.

Unbedingte INSERT ALL : - Um einer Tabelle mehrere Zeilen gleichzeitig hinzuzufügen, verwenden Sie die folgende Form der INSERT-Anweisung:

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

Geben Sie ALL gefolgt von mehreren insert_into_clauses an, um eine bedingungslose multitable Einfügung durchzuführen. Oracle Database führt jede insert_into_clause einmal für jede von der Unterabfrage zurückgegebene Zeile aus.

MySQL Server Mehrere Zeilen einfügen

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

Abfrage zum Einfügen einer einzelnen Zeile

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

Andere hier haben einige Syntaxen für mehrere Datensätze vorgeschlagen. Um dies zu erläutern, schlage ich vor, dass Sie zuerst eine temporäre Tabelle einfügen und von dort aus Ihre Haupttabelle einfügen.

Der Grund dafür ist, dass das Laden der Daten aus einer Abfrage länger dauern kann und Sie möglicherweise die Tabelle oder Seiten länger als erforderlich sperren, wodurch andere Abfragen verlangsamt werden, die für diese Tabelle ausgeführt werden.

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

Außerdem sollten Ihre IDs wahrscheinlich Identität (1,1) sein und Sie sollten sie unter den allermeisten Umständen wahrscheinlich nicht einfügen. Lassen Sie SQL das für Sie entscheiden.

tsilb
quelle