Chèn nhiều hàng MÀ KHÔNG lặp lại phần INS INS IN VÀO Rằng của câu lệnh?


536

Tôi biết tôi đã làm điều này từ nhiều năm trước, nhưng tôi không thể nhớ cú pháp và tôi không thể tìm thấy nó ở bất cứ đâu do kéo theo hàng tấn tài liệu trợ giúp và bài viết về "nhập khẩu số lượng lớn".

Đây là những gì tôi muốn làm, nhưng cú pháp không hoàn toàn chính xác ... làm ơn, ai đó đã làm điều này trước đây, hãy giúp tôi :)

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

Tôi biết rằng đây là gần với cú pháp đúng. Tôi có thể cần từ "BULK" trong đó, hoặc một cái gì đó, tôi không thể nhớ. Bất kỳ ý tưởng?

Tôi cần điều này cho cơ sở dữ liệu SQL Server 2005. Tôi đã thử mã này, nhưng không có kết quả:

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

tôi nhận được Incorrect syntax near the keyword 'VALUES'.


4
Mã ở trên của bạn vẫn ổn chỉ cần thêm ',' sau câu lệnh giá trị
sam

4
XÁC NHẬN VÀO @blah (ID, Tên), GIÁ TRỊ (123, 'Timmy'), GIÁ TRỊ (124, 'Jonny'), GIÁ TRỊ (125, 'Sally')
sam

1
Xin lưu ý: bạn có thể chèn tối đa 1000 hàng chỉ bằng phương pháp này. GIÁ TRỊ VÀO #Test (LWPurchaseOrderID) (935791), (935933)
Anoop Verma

16
Năm 2005 không còn được hỗ trợ. Trong năm 2008, 2012 và 2016, bạn gần như có thể sử dụng những gì bạn đặt INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') "GIÁ TRỊ" chỉ xuất hiện một lần và bạn cần có dấu phẩy giữa các bộ.
J. Chris Compton

Câu trả lời:


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

Đối với SQL Server 2008, có thể thực hiện điều đó trong một mệnh đề GIÁ TRỊ chính xác theo câu lệnh trong câu hỏi của bạn (bạn chỉ cần thêm dấu phẩy để phân tách từng câu lệnh giá trị) ...


10
Đây có phải là bất kỳ hiệu quả hơn so với việc sử dụng nhiều câu lệnh INSERT?
Chỉ huy mã

7
@Code Commander: không, trong đó nó dài hơn để biên dịch. Vâng, trong đó bạn chỉ có một chèn. Nhưng nó trả lời câu hỏi: không lặp lạiINSERT table (columnlist)
gbn

3
@VoidKing Tôi biết điều này xuất hiện nửa năm sau và bạn có thể đã tìm ra điều này từ lâu, nhưng nó thực sự khá đơn giản. Bằng cách sử dụng, selectbạn tạo một tập hợp với các cột và hàng và theo thiết kế, các hàng này có thể được insertchuyển thành một bảng khác với số lượng cột bằng nhau. Bạn thậm chí có thể sử dụng hỗn hợp của nghĩa đen và giá trị. Ví dụ: sử dụng insertvới select 'A', ID from ATablesẽ chèn 'A' vào cột đầu tiên mỗi lần và giá trị cột ID của hàng ATable tương ứng trong cột thứ hai.
MarioDS

1
Điều này cũng hoạt động với DB2, đây là một sidenote quan trọng đối với những người trong chúng ta bị mắc kẹt trong công nghệ lỗi thời. Các giá trị được phân tách bằng câu trả lời bằng dấu phẩy tốt hơn trong suy nghĩ của tôi cho những bạn làm việc trong SQL Server 2008 hoặc mới hơn. OP có thể xóa tất cả "giá trị" ngoại trừ giá trị đầu tiên và thay thế bằng,
JPK

1
@PRMan bạn sẽ không làm điều đó sau phiên bản SQL Server 2008. Như đã đề cập ...
gbn

510

Cú pháp của bạn gần như hoạt động trong SQL Server 2008 (nhưng không phải trong 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 Khi câu hỏi đã được trả lời, không có gì rõ ràng rằng câu hỏi đang đề cập đến SQL Server 2005. Tôi để câu trả lời này ở đây, vì tôi tin rằng nó vẫn còn liên quan.


Hoạt động trong SQL Server 2012
user2601995

27
Máy chủ 2008 không cho phép hơn 1000 hàng được chèn theo cách này.
Michael - Clay Shirky

1
Điều gì xảy ra, nếu một bộ giá trị bị lỗi? Tất cả các chèn sẽ quay trở lại hoặc chỉ hàng bị lỗi?
netblognet

2
@netblognet Tôi vừa kiểm tra rằng chỉ có các hàng bị lỗi không được chèn (tất cả các hàng khác được chèn chính xác)
Mauricio Gracia Gutierrez

1
@Michael Nó có thể được nâng lên stackoverflow.com/a/42703601/5070879
Lukasz Szozda

243

Nếu dữ liệu của bạn đã có trong cơ sở dữ liệu của bạn, bạn có thể làm:

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

Nếu bạn cần mã cứng dữ liệu thì SQL 2008 và các phiên bản mới hơn cho phép bạn thực hiện các thao tác sau ...

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

28

Sử dụng INSERT INTO ... VALUEScú pháp như trong câu trả lời của Daniel Vassallo, có một hạn chế khó chịu:

Từ MSDN

Số lượng hàng tối đa có thể được xây dựng bằng cách chèn các hàng trực tiếp vào danh sách GIÁ TRỊ là 1000

Cách dễ nhất để bỏ qua giới hạn này là sử dụng bảng dẫn xuất như:

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

LiveDemo


Điều này sẽ hoạt động bắt đầu từ SQL Server 2008+


Tôi có thể có một liên kết đến một bài viết về cú pháp 'phụ' này không.
CodeCamper

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

3
Ưu điểm của câu trả lời này là nó cung cấp một cách để xác định các giá trị giống hệt nhau mà không lặp lại chúng (đó là những gì tôi đang tìm kiếm). Ví dụ, với cột thứ ba giống hệt nhau, bạn sẽ không cần lặp lại hàng nghìn lần.
Vadim Berman

1
@VadimBerman Vâng, đó là kịch bản tốt khi không có mặc định được xác định trên bảng.
Lukasz Szozda

14

Bạn có thể làm điều này (xấu nhưng nó hoạt động):

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

10

Điều này sẽ đạt được những gì bạn đang hỏi về:

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

Đối với các nhà phát triển trong tương lai, bạn cũng có thể chèn từ một bảng khác :

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

Hoặc thậm chí từ nhiều bảng :

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

8

Bạn có thể sử dụng một liên minh:

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

Điều này có vẻ ổn đối với SQL Server 2008. Đối với SS2005 trở về trước, bạn cần lặp lại câu lệnh VALUES.

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

EDIT :: xấu của tôi. Bạn phải lặp lại 'XÁC NHẬN VÀO' cho mỗi hàng trong 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

Sẽ dễ dàng hơn khi sử dụng XML trong SQL Server để chèn nhiều hàng nếu không nó trở nên rất tẻ nhạt.

Xem bài viết đầy đủ với các giải thích về mã ở đây http://www.cyberminds.co.uk/blog/articles/how-to-insert-multipl-rows-in-sql-server.aspx

Sao chép mã sau vào máy chủ sql để xem mẫu.

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

HOẶC BẠN CÓ THỂ SỬ DỤNG CÁCH KHÁC

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

6

Tôi đã sử dụng như sau:

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

Nó sẽ thêm mười hàng với GUID duy nhất cho ID và Tên.

Lưu ý: không kết thúc dòng cuối cùng (GO 10) bằng ';' bởi vì nó sẽ ném lỗi: Xảy ra lỗi kịch bản nghiêm trọng. Cú pháp không chính xác đã gặp phải khi phân tích cú pháp GO.


5

Tương ứng với INSERT (Transact-SQL) (SQL Server 2005), bạn không thể bỏ qua INSERT INTO dbo.Blahvà phải chỉ định nó mỗi lần hoặc sử dụng cú pháp / cách tiếp cận khác,


2

Điều này đang làm việc rất nhanh và hiệu quả trong SQL. Giả sử bạn có Bảng 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
)

Vì vậy, bạn không thể chèn nhiều bản ghi trong bảng này bằng cách sử dụng truy vấn sau mà không lặp lại câu lệnh chèn,

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)

Ngoài ra với C # sử dụng SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

Bạn có thể chèn 10 hàng cùng một lúc

   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

Máy chủ Oracle SQL Chèn nhiều hàng

Trong phần chèn đa năng, bạn chèn các hàng được tính toán xuất phát từ các hàng được trả về từ việc đánh giá truy vấn con vào một hoặc nhiều bảng.

Vô điều kiện TẤT CẢ : - Để thêm nhiều hàng vào một bảng, bạn sử dụng mẫu sau của câu lệnh 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

Chỉ định TẤT CẢ theo sau bởi nhiều insert_into_clauses để thực hiện chèn đa năng vô điều kiện. Cơ sở dữ liệu Oracle thực thi mỗi insert_into_clse một lần cho mỗi hàng được trả về bởi truy vấn con.

Máy chủ MySQL Chèn nhiều hàng

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

Truy vấn chèn một hàng

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

0

Những người khác ở đây đã đề xuất một vài cú pháp nhiều bản ghi. Trước đó, tôi khuyên bạn nên chèn vào bảng tạm thời và chèn bảng chính của bạn từ đó.

Lý do cho việc này là tải dữ liệu từ một truy vấn có thể mất nhiều thời gian hơn và cuối cùng bạn có thể khóa bảng hoặc trang lâu hơn mức cần thiết, điều này làm chậm các truy vấn khác chạy trên bảng đó.

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

Ngoài ra, ID của bạn có thể phải là danh tính (1,1) và có lẽ bạn không nên chèn chúng, trong phần lớn các trường hợp. Hãy để SQL quyết định những thứ đó cho bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.