Inserire più righe SENZA ripetere la parte "INSERIRE IN ..." dell'istruzione?


536

So di averlo fatto prima di anni fa, ma non ricordo la sintassi e non riesco a trovarla da nessuna parte a causa di tonnellate di documenti e articoli di aiuto sulle "importazioni di massa".

Ecco cosa voglio fare, ma la sintassi non è esattamente corretta ... per favore, qualcuno che l'ha già fatto prima, aiutami :)

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

So che questo è vicino alla sintassi giusta. Potrei aver bisogno della parola "BULK" o qualcosa che non ricordo. Qualche idea?

Ho bisogno di questo per un database SQL Server 2005. Ho provato questo codice, inutilmente:

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

Sto ottenendo Incorrect syntax near the keyword 'VALUES'.


4
Il tuo codice sopra va bene basta aggiungere ',' dopo la dichiarazione dei valori
sam

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

1
Solo un avvertimento: puoi inserire fino a 1000 righe solo con questo metodo. INSERISCI SU VALORI #Test (LWPurchaseOrderID) (935791), (935933)
Anoop Verma

16
Il 2005 non è più supportato. Per il 2008, 2012 e 2016 puoi quasi usare ciò che metti INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') "VALORI" appare solo una volta e hai bisogno di virgole tra i set.
J. Chris Compton,

Risposte:


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

Per SQL Server 2008, puoi farlo in una clausola VALUES esattamente come per l'istruzione nella tua domanda (devi solo aggiungere una virgola per separare ogni istruzione di valori) ...


10
È più efficace dell'uso di più istruzioni INSERT?
Codice comandante

7
@Code Commander: no, in quanto è più lungo da compilare. Sì, in quanto hai un solo inserto. Ma risponde alla domanda: nessuna ripetizione diINSERT table (columnlist)
gbn

3
@VoidKing So che arriva dopo sei mesi e potresti averlo capito molto tempo fa, ma è davvero abbastanza semplice. Usando selectsi crea un set con colonne e righe e, in base alla progettazione, queste righe possono essere insertinserite in un'altra tabella con un uguale numero di colonne. Puoi persino usare una combinazione di valori letterali e valori. Ad esempio, l'utilizzo insertcon select 'A', ID from ATableinserisce ogni volta 'A' nella prima colonna e il valore della colonna ID della riga corrispondente di ATable nella seconda colonna.
MarioDS,

1
Questo funziona anche con DB2, che è un sidenote importante per quelli di noi bloccati nella tecnologia obsoleta. I valori separati dalla virgola rispondono meglio a quelli che lavorano in SQL Server 2008 o versioni successive. L'OP può rimuovere tutti i "valori" tranne il primo e sostituirlo con un,
JPK

1
@PRMan non lo faresti dopo la versione SQL Server 2008. Come detto ...
gbn

510

La sintassi funziona quasi in SQL Server 2008 (ma non 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 Alla risposta alla domanda, non è stato reso evidente che la domanda si riferiva a SQL Server 2005. Lascio questa risposta qui, poiché ritengo che sia ancora pertinente.


Funziona in SQL Server 2012
user2601995 il

27
Server 2008 non consente più di 1000 righe inserite in questo modo.
Michael - Dov'è Clay Shirky il

1
Cosa succede se un valore impostato è difettoso? Verranno ripristinati tutti gli inserti o solo la riga difettosa?
netblognet,

2
@netblognet Ho appena provato che non sono state inserite solo righe difettose (tutte le altre sono inserite correttamente)
Mauricio Gracia Gutierrez,

1
@ Michael Potrebbe essere sollevato stackoverflow.com/a/42703601/5070879
Lukasz Szozda

243

Se i tuoi dati sono già nel tuo database puoi fare:

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

Se è necessario codificare i dati in modo rigido, SQL 2008 e le versioni successive consentono di eseguire le seguenti operazioni ...

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

28

Usando la INSERT INTO ... VALUESsintassi come nella risposta di Daniel Vassallo c'è una fastidiosa limitazione:

Da MSDN

Il numero massimo di righe che è possibile costruire inserendo le righe direttamente nell'elenco VALORI è 1000

Il modo più semplice per omettere questa limitazione è usare una tabella derivata come:

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

LiveDemo


Funzionerà a partire da SQL Server 2008+


Posso avere un link ad un articolo su questa sintassi 'sub'.
CodeCamper

2
Sezione @CodeCamper docs.microsoft.com/en-us/sql/t-sql/queries/… :C. Specifying multiple values as a derived table in a FROM clause
Lukasz Szozda

3
Il vantaggio di questa risposta è che fornisce un modo per specificare valori identici senza ripeterli (che è quello che stavo cercando). Ad esempio con una terza colonna identica, non è necessario ripeterla per mille volte.
Vadim Berman,

1
@VadimBerman Sì, questo è uno scenario valido quando non esiste alcun valore predefinito definito nella tabella.
Lukasz Szozda,

14

Potresti farlo (brutto ma funziona):

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

10

Ciò consentirà di ottenere ciò che stai chiedendo:

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

Per i futuri sviluppatori, puoi anche inserire da un'altra tabella :

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

O anche da più tabelle :

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

8

Puoi usare un'unione:

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

Questo sembra OK per SQL Server 2008. Per SS2005 e precedenti, è necessario ripetere l'istruzione VALUES.

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

EDIT :: Mio cattivo. Devi ripetere 'INSERT INTO' per ogni riga in SS2005.

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

Sarebbe più semplice utilizzare XML in SQL Server per inserire più righe altrimenti diventa molto noioso.

Visualizza l'articolo completo con spiegazioni del codice qui http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

Copia il codice seguente nel server sql per visualizzare un esempio.

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

O PUOI USARE UN ALTRO MODO

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

6

Ho usato il seguente:

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

Aggiungerà dieci righe con GUID univoci per ID e nome.

Nota: non terminare l'ultima riga (GO 10) con ';' perché genererà un errore: si è verificato un errore di scripting irreversibile. Si è verificata una sintassi errata durante l'analisi di GO.


5

Corrispondente a INSERT (Transact-SQL) (SQL Server 2005) non è possibile omettere INSERT INTO dbo.Blahe specificare ogni volta o utilizzare un'altra sintassi / approccio,


2

Funziona molto velocemente ed è efficiente in SQL. Supponiamo di avere un tavolo 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
)

Quindi non puoi inserire più record in questa tabella usando la seguente query senza ripetere l'istruzione insert,

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)

Anche con C # usando SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

Puoi inserire 10 righe alla volta

   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 Inserisci più righe

In un inserto a più voci, si inseriscono le righe calcolate derivate dalle righe restituite dalla valutazione di una sottoquery in una o più tabelle.

INSERISCI TUTTO incondizionato : - Per aggiungere più righe contemporaneamente a una tabella, utilizzare il seguente modulo dell'istruzione 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

Specificare ALL seguito da più insert_into_clause per eseguire un inserimento multitable incondizionato. Oracle Database esegue ogni insert_into_clause una volta per ogni riga restituita dalla sottoquery.

Server MySQL Inserisci più righe

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

Query di inserimento a riga singola

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

0

Altri qui hanno suggerito un paio di sintassi multi-record. In conclusione, ti suggerisco di inserire prima una tabella temporanea e di inserire la tabella principale da lì.

Il motivo è che il caricamento dei dati da una query può richiedere più tempo e si potrebbe finire per bloccare la tabella o le pagine più a lungo del necessario, il che rallenta altre query in esecuzione su quella tabella.

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

Inoltre, i tuoi ID dovrebbero probabilmente essere identità (1,1) e probabilmente non dovresti inserirli, nella stragrande maggioranza delle circostanze. Lascia che SQL decida per te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.