Masukkan beberapa baris TANPA mengulangi bagian "INSERT INTO ..." dari pernyataan?

536

Saya tahu saya telah melakukan ini sebelum tahun lalu, tetapi saya tidak dapat mengingat sintaksnya, dan saya tidak dapat menemukannya di mana pun karena menarik banyak dokumen bantuan dan artikel tentang "impor massal".

Inilah yang ingin saya lakukan, tetapi sintaksnya tidak tepat benar ... tolong, seseorang yang telah melakukan ini sebelumnya, bantu saya :)

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

Saya tahu bahwa ini dekat dengan sintaks yang tepat. Saya mungkin memerlukan kata "BULK" di sana, atau sesuatu, saya tidak ingat. Ada ide?

Saya memerlukan ini untuk database SQL Server 2005. Saya sudah mencoba kode ini, tetapi tidak berhasil:

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

Saya mengerti Incorrect syntax near the keyword 'VALUES'.

Timothy Khouri
sumber
4
Kode di atas Anda baik-baik saja hanya perlu menambahkan ',' setelah pernyataan nilai
sam
4
INSERT INTO @blah (ID, Name), VALUES (123, 'Timmy'), VALUES (124, 'Jonny'), VALUES (125, 'Sally')
sam
1
Hanya peringatan: Anda dapat memasukkan hingga 1000 baris hanya dengan metode ini. INSERT INTO #Test (LWPurchaseOrderID) VALUES (935791), (935933)
Anoop Verma
16
2005 tidak lagi didukung. Untuk 2008, 2012 dan 2016 Anda hampir dapat menggunakan apa yang Anda masukkan INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') "VALUES" hanya muncul sekali dan Anda perlu koma di antara set.
J. Chris Compton

Jawaban:

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

Untuk SQL Server 2008, dapat melakukannya dalam satu klausa NILAI persis seperti pernyataan dalam pertanyaan Anda (Anda hanya perlu menambahkan koma untuk memisahkan setiap pernyataan nilai) ...

gbn
sumber
10
Apakah ini lebih efisien daripada menggunakan beberapa pernyataan INSERT?
Code Commander
7
@Code Commander: tidak, karena lebih lama untuk dikompilasi. Ya, karena Anda hanya memiliki satu sisipan. Tapi itu menjawab pertanyaan: tidak ada pengulanganINSERT table (columnlist)
gbn
3
@VoidKing Saya tahu ini terjadi setengah tahun kemudian dan Anda mungkin sudah menemukan ini sejak lama, tapi itu benar-benar sangat sederhana. Dengan menggunakan selectAnda membuat satu set dengan kolom dan baris, dan dengan desain baris ini dapat insertdiedit ke tabel lain dengan jumlah kolom yang sama. Anda bahkan dapat menggunakan campuran literal dan nilai-nilai. Misalnya, menggunakan insertdengan select 'A', ID from ATableakan memasukkan 'A' di kolom pertama setiap kali dan nilai kolom ID dari baris ATable yang sesuai di kolom kedua.
MarioDS
1
Ini juga bekerja dengan DB2 yang merupakan identitas penting bagi kita yang terjebak dalam teknologi yang sudah ketinggalan zaman. Nilai-nilai yang dipisahkan oleh koma jawaban lebih baik dalam pikiran saya bagi Anda yang bekerja di SQL Server 2008 atau yang lebih baru. OP dapat menghapus semua "nilai" kecuali yang pertama dan ganti dengan,
JPK
1
@ PRMan Anda tidak akan melakukan itu setelah versi SQL Server 2008. Seperti disebutkan ...
gbn
510

Sintaks Anda hampir berfungsi di SQL Server 2008 (tetapi tidak di 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 Ketika pertanyaan dijawab, itu tidak dibuat jelas bahwa pertanyaan itu merujuk ke SQL Server 2005. Saya meninggalkan jawaban ini di sini, karena saya percaya itu masih relevan.

Daniel Vassallo
sumber
Bekerja di SQL Server 2012
user2601995
27
Server 2008 tidak mengizinkan lebih dari 1000 baris dimasukkan dengan cara ini.
Michael - Di mana Clay Shirky
1
Apa yang terjadi, jika satu set nilai salah? Apakah semua sisipan dibatalkan atau hanya baris yang salah?
netblognet
2
@netblognet Saya baru saja menguji bahwa hanya baris yang salah tidak dimasukkan (semua yang lain dimasukkan dengan benar)
Mauricio Gracia Gutierrez
1
@Michael Bisa diangkat stackoverflow.com/a/42703601/5070879
Lukasz Szozda
243

Jika data Anda sudah ada di database Anda, Anda dapat melakukan:

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

Jika Anda perlu mengode data, SQL 2008 dan versi yang lebih baru memungkinkan Anda melakukan hal berikut ...

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

Menggunakan INSERT INTO ... VALUESsintaksis seperti dalam jawaban Daniel Vassallo ada satu batasan yang mengganggu:

Dari MSDN

Jumlah maksimum baris yang dapat dibangun dengan memasukkan baris secara langsung dalam daftar VALUES adalah 1000

Cara termudah untuk menghilangkan batasan ini adalah dengan menggunakan tabel turunan seperti:

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

LiveDemo


Ini akan bekerja mulai dari SQL Server 2008+

Lukasz Szozda
sumber
Dapatkah saya memiliki tautan ke artikel tentang sintaks 'sub' ini.
CodeCamper
2
@CodeCamper docs.microsoft.com/en-us/sql/t-sql/queries/… bagian:C. Specifying multiple values as a derived table in a FROM clause
Lukasz Szozda
3
Keuntungan dari jawaban ini adalah bahwa ia menyediakan cara untuk menentukan nilai yang identik tanpa mengulanginya (yang saya cari). Misalnya dengan kolom ketiga yang identik, Anda tidak perlu mengulanginya ribuan kali.
Vadim Berman
1
@ VadimBerman Ya, itu skenario yang bagus ketika tidak ada default yang ditentukan pada tabel.
Lukasz Szozda
14

Anda bisa melakukan ini (jelek tapi berhasil):

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

Ini akan mencapai apa yang Anda tanyakan:

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

Untuk pengembang masa depan, Anda juga dapat menyisipkan dari tabel lain :

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

Atau bahkan dari beberapa tabel :

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

Anda bisa menggunakan gabungan:

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

Ini terlihat OK untuk SQL Server 2008. Untuk SS2005 & sebelumnya, Anda perlu mengulangi pernyataan VALUES.

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

EDIT :: Buruk saya. Anda harus mengulangi 'INSERT INTO' untuk setiap baris di 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')  
DaveE
sumber
6

Akan lebih mudah untuk menggunakan XML dalam SQL Server untuk memasukkan banyak baris jika tidak maka akan sangat membosankan.

Lihat artikel lengkap dengan penjelasan kode di sini http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

Salin kode berikut ke server sql untuk melihat sampel.

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

ATAU ANDA BISA MENGGUNAKAN CARA LAIN

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

Saya telah menggunakan yang berikut ini:

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

Ini akan menambahkan sepuluh baris dengan GUID unik untuk ID dan Nama.

Catatan: jangan akhiri baris terakhir (GO 10) dengan ';' karena akan menimbulkan kesalahan: Terjadi kesalahan penulisan skrip yang fatal. Sintaks yang salah ditemui saat mem-parsing GO.

valentinvs
sumber
5

Sesuai dengan INSERT (Transact-SQL) (SQL Server 2005) Anda tidak dapat menghilangkan INSERT INTO dbo.Blahdan harus menentukan setiap kali atau menggunakan sintaks / pendekatan lain,

abatishchev
sumber
2

Ini bekerja sangat cepat, dan efisien dalam SQL. Misalkan Anda memiliki 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
)

Jadi Anda tidak bisa menyisipkan beberapa catatan dalam tabel ini menggunakan kueri berikut tanpa mengulangi pernyataan 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)

Juga Dengan C # menggunakan SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

Anda dapat memasukkan 10 baris sekaligus

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

Oracle SQL Server, Masukkan Banyak Baris

Dalam menyisipkan multitable, Anda menyisipkan baris dihitung yang berasal dari baris yang dikembalikan dari evaluasi subquery ke dalam satu atau beberapa tabel.

Masukkan tanpa syarat SEMUA : - Untuk menambahkan beberapa baris ke tabel sekaligus, Anda menggunakan bentuk pernyataan INSERT berikut ini:

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

Tentukan SEMUA diikuti oleh multiple insert_into_clauses untuk melakukan insert multitable tanpa syarat. Oracle Database mengeksekusi setiap insert_into_clause sekali untuk setiap baris yang dikembalikan oleh subquery.

Server MySQL Masukkan Banyak Baris

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

Baris permintaan tunggal

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

Lainnya di sini telah menyarankan beberapa sintaks multi-record. Menguraikan hal itu, saya sarankan Anda memasukkan ke dalam tabel temp pertama, dan masukkan tabel utama Anda dari sana.

Alasannya adalah memuat data dari kueri bisa memakan waktu lebih lama, dan Anda mungkin akhirnya mengunci tabel atau halaman lebih lama dari yang diperlukan, yang memperlambat kueri lain yang berjalan melawan tabel itu.

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

Selain itu, ID Anda mungkin harus berupa identitas (1,1) dan Anda mungkin tidak boleh memasukkannya, dalam sebagian besar keadaan. Biarkan SQL memutuskan hal itu untuk Anda.

tsilb
sumber