This is a very interesting question I have received from new development. How can I insert multiple records in a table using only one insert? Now this is an interesting question. When there are multiple records to be inserted in the table, the following is the common way using T-SQL.

USE YourDB
GO
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('First',1);
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('Second',2);
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('Third',3);
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('Fourth',4);
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('Fifth',5);
GOThe short answer today
If you are on SQL Server 2008 or anything newer, which is everybody by now, one INSERT can carry all the rows. Separate each row with a comma and you are done.
USE YourDB
GO
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('First', 1),
('Second', 2),
('Third', 3),
('Fourth', 4),
('Fifth', 5);
GOThis is called the row constructor, or the table value constructor if you like the long name. It is shorter to write, easier to read, and it is one statement rather than five, so the server does less work. Start here.
One limit worth remembering: a single VALUES list can hold 1,000 rows. Go past that and SQL Server refuses. If you have more rows than that, split them into batches of a thousand, or load them from a file instead.
The UNION ALL way, and why it is still here
The clause INSERT INTO is repeated multiple times above. Many times DBA copy and paste it to save time. There is another alternative to this, which I used for years before the row constructor arrived. I use UNION ALL and INSERT INTO … SELECT… Clauses.
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
The effective result is same. Two reasons this one has not gone away. It has no thousand row limit, so it is handy for a long generated script. And every row is a SELECT, so you can mix in expressions, GETDATE, or a lookup from another table on any line without changing the shape of the statement.
Use UNION ALL and not UNION. UNION quietly removes duplicate rows, so if two of your rows are identical, one of them will never reach the table and you will spend an afternoon working out why.
If the rows already exist somewhere
Plenty of people land here wanting to copy rows from one table to another rather than type them out. That is a different statement, and a simpler one.
INSERT INTO MyTable (FirstCol, SecondCol) SELECT FirstCol, SecondCol FROM SomeOtherTable WHERE SecondCol > 10;
No VALUES, no UNION ALL, and no row limit. The column list on the INSERT and the column list on the SELECT have to line up in order and in type, which is the only part people get wrong.
Which one should you use
Up to a thousand rows that you are typing by hand, use the row constructor. More than a thousand, or rows built from expressions, use UNION ALL. Rows that already live in another table, use INSERT INTO … SELECT. Thousands of rows arriving from a file, do not use any of these, use BULK INSERT.
Update: the row constructor shown above first arrived in SQL Server 2008, and I wrote about it separately here: SQL SERVER Insert Multiple Records Using One Insert Statement – Use of Row Constructor
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.





875 Comments. Leave new
one table for example marksheet use id = pk and rollno use table insert data roll no is same no are display in dtabase .how to solved that rollno is not same enter to insert time
How can I insert more than 1000 rows in a temp table
Create table #temp (i int)
go
insert into #temp (1)
go 1000
sir I am stuck in a logic ..
I have dynamic tables . lets say one large data Big_Table is stamped with profile 1,2,3,….n
so i create table profile1,profile2,… profilen (example profile1 :- select * from Big_Table where rule = profile1)
table data example :-
table_profile1
transaction_id profile priority
1 1 1
2 1 1
table_profile2
transaction_id profile priority
1 2 2
3 2 1
now lets say we got single transaction in Big table is repeated in table_profile1 and table_profile2
so i need to pick all data of table_profile1,table_profile2,table_profilen with lower Priority
so here in target transaction_id 2 is repeated in profile1 and profile2 table so final table will have only transaction id 2 with lower priority of profile 1 as its 1
Big_table_stamped
transaction_id profile priority
1 1 1
2 1 1
3 2 1
so this final stamped table Big_table_stamped
query i am dynamically creating is
select transaction_id,profile,priority
from (
select row_number() over (partition by a.transaction_id order by a.priority asc) r
a.*
from (
select * from table_profile1
union all
select * from table_profile2
union all
.
union all
select * from table_profilen
) a
) data
where data.r=1
)
but this is slow … i may have 600 tables too..
sholud i first put all data in one table ..
we broke tables to make faster process
should i join all tables .
or what should be my approach
I dont have much time
how to insert more than 500 records into table without duplicates
There seems to be no need to use either extra insert statements or union clauses. Why do you prefer the use of union?
My way to insert multiple records would look like this:
insert into TESTNILS (ZAHL, TEXT) values (1,’eins’), (2,’zwei’), (3, ‘drei’), ….
Nils
When this article was written at that time the new syntax which you suggested was available in SQL Server.
I hope this helps.
Hi Pinal,
I just saw your tweet with the link to this post. To make it more valuable, I would suggest adding this example:
INSERT INTO MyTable (FirstCol, SecondCol) VALUES (‘First’,1), (‘Second’,2), (‘Third’,3);
Regards,
Goran
Great suggestion.
Great one
Suppose I have a list of comma separated numbers
123,
345,
888,
999
I want to insert them in a temp table, how would I be able to do this?
Sir, What to do in case if I want to insert IMAGE also (as byte array) ? How can I use the same syntax ? Is there any idea?
Can we use xml for multiple insert?
Thankyou, It is great suggestion.