SQL SERVER – Insert Multiple Records Using One Insert Statement – Use of UNION ALL

Update: In SQL Server 2008 there is an even better method of Row Construction for inserting multiple records, please read it here: SQL SERVER Insert Multiple Records Using One Insert Statement – Use of Row Constructor

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

SQL SERVER - Insert Multiple Records Using One Insert Statement - Use of UNION ALL fullouter_join

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);
GO

The clause INSERT INTO is repeated multiple times. Many times DBA copy and paste it to save time. There is another alternative to this, which I use frequently. I use UNION ALL and INSERT INTO … SELECT… Clauses. Regarding performance there is not much difference. If there is performance difference it does not matter as I use this for one time insert script. I enjoy writing this way, as it keeps my focus on the task, instead of copy paste. I have explained following script to new developers. He was quite pleased.

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.

Reference : Pinal Dave (https://blog.sqlauthority.com) , SQL SERVER – Union vs. Union All – Which is better for performance?

Best Practices, Database, SQL Scripts, SQL Server, SQL Union clause
Previous Post
SQL SERVER – 2005 Download New Updated Book On Line (BOL)
Next Post
SQL SERVER – UDF – Function to Display Current Week Date and Day – Weekly Calendar

Related Posts

876 Comments. Leave new

  • oh, um the test was run on 5,000 rows.

    Reply
  • Hi Pinal,
    iam Really very happy to see your website.It is really Healpful for me.
    Best of luck

    Reply
  • Hi Pinal,

    i am trying to do multiple inserts from a table to the same table by changing a field value and i am also have the increment the id ( primary key ) by 1 with each insertion.

    How can i increment the recordid with each insertion?
    ( i should not use identity auto increment )

    i tried …

    insert into table (id,…..)
    select (max(id) + 1), …. from table

    ERROR: Violation of PRIMARY KEY constraint ‘PK_IDtable1’. Cannot insert duplicate key in object ‘dbo.table1’.

    Reply
  • Hi,
    I have written following procedure for inser, where I want to pass table name from application program. But its not working. Same format works for create table.

    This procedure giving me error as
    Error converting data type varchar to datetime.

    my procedure is
    Create PROCEDURE [dbo].[InsertSalesOrderDetail]
    (
    @tablename varchar(20),
    @SalesOrderID int,
    @SalesOrderDetailID int,
    @CarrierTrackingNumber nvarchar(25),
    @OrderQty smallint,
    @ProductID int,
    @SpecialOfferID int,
    @UnitPrice money,
    @UnitPriceDiscount money,
    @LineTotal money,
    @rowguid nvarchar (50),
    @ModifiedDate datetime)
    AS
    BEGIN

    SET NOCOUNT ON;

    exec(‘ INSERT INTO [AdventureWorks].[dbo].[‘+ @tablename +’ ]
    values( @SalesOrderID,@SalesOrderDetailID,@CarrierTrackingNumber,@OrderQty,@ProductID,
    @SpecialOfferID,@UnitPrice,@UnitPriceDiscount,@LineTotal,@rowguid ,@ModifiedDate ) ‘)

    END;

    pls help
    tell me how to pass table name, if we specify the table name in query, then it works.
    Thanks

    Reply
  • The same procedure gives error :

    Must declare the scalar variable “@SalesOrderID”.

    I have declared this variable……
    pls help
    thanks

    Reply
  • I want to know how to insert a multiple rows to a table using ‘&’ symbol in SQL query….Please do help me…

    Reply
  • Thanks for sharing valuable tips here. Really it helps lot.

    Reply
  • You indeed get a big performance increase, but if you try to use this method where it really counts (like inserting 100k records) it will crash your query compiler and fail to execute. A query simply can’t be that big and complex. Optimizing inserts like this is possible only on mysql.

    Reply
  • I have a stored procedure:
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    GO

    ALTER PROCEDURE [dbo].[sp_InsertIMEIDetails]
    @XMLDOC varchar(8000)
    AS

    Declare @xml_hndl int

    exec sp_xml_preparedocument @xml_hndl OUTPUT, @XMLDOC

    BEGIN
    INSERT INTO IMEI_IMEIDetails (SerialNumber)
    SELECT SerialFrom
    FROM OPENXML(@xml_hndl,’//SerialNumbers/SerialFrom’,1)
    With (SerialFrom varchar ‘@id’)
    END

    I want to insert a series that the user will enter from the form the series will start from “000000” and will end on “999999” so we are talking about an insertion of 10 Lakh records in one go and the second problem is I want to store the numbers in the same format as they are getting entered.

    Hope I am making sense here, can some one help me on this ASAP.

    Thanks!

    Reply
  • hi,

    i have a little doubt related to insert query.

    i have a form in which i have 7 text boxes.
    2 text box values stores in table customer.
    5 text box values stores in table address.

    and i have relate these 2 tables with a foreign key i.e, customer_id is added as new column in address table.

    Question?
    i want to insert the customer_id into table address as when click the submit button of the form.
    and i am inserting all the values from a single Stored procedure first inserting table customer values then tables address values.

    so plz tell me how can i do this.

    thanks in advance

    Reply
  • Thanks a lot! This was very useful and saved me tons of time.

    Reply
  • Hi,

    Thanks for this tutorials, it’s cool and really helps me a lot in solving my problem.

    Hope to know more from you.

    Thanks!

    Reply
  • Hi
    I created below store procedure to update the flag of status to 4 from 2.This will invoke when user hit my web site because written in global.cs file under application_beginrequest event in asp.net.Already so many records will got expired and in status 4 but i need the data of last updated records.

    SET QUOTED_IDENTIFIER OFF
    GO
    SET ANSI_NULLS OFF
    GO
    Create PROCEDURE adStatusUpdate AS
    UPDATE [addetails] set ad_status = 4
    WHERE (ad_status = 2) AND ( ( DATEADD(dd, ad_validity, ad_publishing_date) <= getdate() ))
    GO
    SET QUOTED_IDENTIFIER OFF
    GO
    SET ANSI_NULLS ON
    GO

    Actually i want to expire an ad after validty period get over and also notify user about expiry of their ad using mail.

    when i update a query it will display 12 records updated instead Can i get the last updated records like select query so that it will be useful to get their mailids from respective tables or can i store the updated records in another table using insert query

    insert into tablename
    values (UPDATE [addetails] set ad_status = 4
    WHERE (ad_status = 2) AND ( ( DATEADD(dd, ad_validity, ad_publishing_date) <= getdate() )) )

    or

    select * from aduser (UPDATE [addetails] set ad_status = 4 WHERE (ad_status = 2) AND ( ( DATEADD(dd, ad_validity, ad_publishing_date) <= getdate() )) )

    select userdetails.user_email,addetails.ad_title,
    addetails.auth_code,addetails.ad_status,
    addetails.ad_publishing_date
    from userdetails inner join addetails
    on addetails.auth_code=userdetails.auth_code
    and addetails.ad_status = 2 AND ( ( DATEADD(dd, ad_validity, ad_publishing_date) <= getdate() ))

    Kindly sort out my problem else provide me alternate solution to match my scenario.

    Thanks in advance.

    Reply
  • Hi all,

    I tried to run the following query an obviouly i didn’t execute. I know this is terribly wrong. Please help me out. The select statement is to get values from another table and it will return ultiple values which I have to insert into reasonforchange table.

    insert into reasonforchange(reasonforchange_id,reasonforchange) values
    (newid(),select distinct displayvalue from oc_picklistvalues pv inner join oc_picklistlanguages pl
    on pv.picklistid=pl.picklistid where pl.shortdescription=’Reason for Change’and pv.displayvalue=’Promotion’)

    Reply
  • Imran Mohammed
    January 30, 2009 9:32 am

    @Arvind,

    The query is failing because the select statement is returning more than one value.

    Test if the query works, using select top 1 ……. something like this,

    insert into reasonforchange(reasonforchange_id,reasonforchange) values
    (newid(),select top 1 displayvalue from oc_picklistvalues pv inner join oc_picklistlanguages pl
    on pv.picklistid=pl.picklistid where pl.shortdescription=’Reason for Change’and pv.displayvalue=’Promotion’)

    Work Around : Why don’t you create a default on ReasonForChange column , keep the default as newid(), then insert statement will be,

    insert into reasonforchange (reasonforchange) select distinct displayvalue from oc_picklistvalues pv inner join oc_picklistlanguages pl
    on pv.picklistid=pl.picklistid where pl.shortdescription=’Reason for Change’and pv.displayvalue=’Promotion’

    Hope this helps,

    Regards,
    IM.

    Reply
  • how can i set the logging options through the database management interface in sql server 2005

    Reply
  • Actually i want, Record logging shall be handled within the database, and not within the application. The user
    shall set the logging options through the database management interface in SQL Server 2005.

    Reply
  • Very good concept

    Reply
  • Hi ,

    I want to insert value into particular column,there is any statement like using “where” condition…”insert table table_name values value1 where id=111″ etc.
    Please let us know if any statements like..

    Thanks and Regards,
    Phani..

    Reply
  • Hi Pinal:
    I am stack in a piculiar situation.
    I have a stored proc (SQL 2005) which is compilled and executed successfully. I used cursor in my stored proc.
    Stored proc executes on a table and match data with another table dada. So it will either update existing data or if new data come will insert new data into second table.
    My updating command is working ok. But inserting commend is not working. I know in my first table I habe 7 new data which are waiting to insetr into second table.
    I’m trying to find it out where is the problem but couldn’t.
    Would you please help me. I have to delivery my project by the end of the second week but I’m stack here.
    Here is my Stored proc:

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    GO
    ALTER procedure [dbo].[AddMonth_Event_TotalInfo]
    –@fiscalYear int
    as
    Declare
    C1 CURSOR READ_ONLY
    FOR
    SELECT CONVERT(varchar(7), IdsData.EarliestEvent, 111) AS [Yr-Mon], TagType.TagTypeID AS EventID, ISNULL(SUM(IdsData.EventCount), 0) AS Total
    FROM TagType INNER JOIN
    TagDetails ON TagType.TagTypeID = TagDetails.TagTypeID INNER JOIN
    IdsData ON TagDetails.[TagName (Unique)] = IdsData.TagName INNER JOIN
    SensorCategories ON IdsData.AgentIP = SensorCategories.SensorIP
    WHERE (SensorCategories.Monthly = ‘Y’)
    GROUP BY CONVERT(varchar(7), IdsData.EarliestEvent, 111), TagType.TagTypeID
    ORDER BY [Yr-Mon], EventID

    Declare
    @MonthID int,
    @EventMonth varchar(7),
    –@EventName varchar(30),
    @EventID int,
    @Total int,
    @EventTotal int

    –delete from Month_Event_TotalInfo

    OPEN C1
    FETCH NEXT FROM C1
    INTO @EventMonth,@EventID,@EventTotal

    WHILE @@FETCH_STATUS = 0
    BEGIN
    SELECT @MonthID=isnull(MAX(Month_ID),0)+1 from Month_Event_TotalInfo

    select @Total=Event_Total from Month_Event_TotalInfo where Event_Month=@EventMonth
    and Event_ID=@EventID
    if (@Total>=0)
    update Month_Event_TotalInfo
    set Event_Total=@EventTotal where Event_Month=@EventMonth and Event_ID=@EventID
    else
    insert into Month_Event_TotalInfo(Month_Id,Event_Month,Event_ID,Event_Total)
    values (@MonthID,@EventMonth,@EventID,@EventTotal)

    FETCH NEXT FROM C1
    INTO @EventMonth,@EventID,@EventTotal
    END
    CLOSE C1

    DEALLOCATE C1

    Reply

Leave a Reply