Bulk Data Transactions Using OPENXML
The Problem
You want to insert 5000 records into the database. You normally do this by creating a separate insert statement for each record, and this is fine with your boss, but youâre a glutton for punishment and want to optimize this scenario because it occurs often enough in your application. On the other hand, youâre also lazy, have ten thousand interesting things to do, and would love to not have to spend a lot of time tackling the problem. Oh, and youâll be using stored procedures because, as everyone knows, theyâre better than dynamic SQL. So? What do you do?
Enter OPENXML
OPENXML is a nice little function that will allow us to solve the above-mentioned problem without feeling like weâre hacking our way through it. The need for a hack wouldnât arise if we can just send any number of parameters that we want to the stored procedure; i.e., in .NET, we have the params[] array, and in Javascript, we have the args array, but in stored procedures, we donât have any such luxury.
The code, then, of the stored procedure that bulk-inserts data into a table using OPENXML:
- CREATE procedure [dbo].[openxml_test]
- @xmlDocument text
- as
- declare @handle int
- exec sp_xml_preparedocument @handle output, @xmlDocument
- begin
- set nocount on;
- insert into openxml_test_db(ID, random_data)
- select tid, tdata from openxml(@handle, NâROOT/Threadâ, 2)
- with (tid uniqueidentifier, tdata varchar(100))
- exec sp_xml_removedocument @handle
- end
The XML structure is going to be of the form:
- <ROOT>
- <Thread>
- <TGuid>cf69e831-4b82-43bc-bc0c-00013af696d3</TGuid>
- <TData>An awful lot of data</TData>
- </Thread>
- </ROOT>
What Weâre Doing
Line 3: Sending the variable as text is less effecient than sending it as varchar(8000). If youâre reasonably sure that your xml (including the tags, data, and all) that you send to the stored procedure isnât going to exceed 8000 characters in length, I suggest you use that instead.
Line 9: sp_xml_preparedocument is a system stored procedure that, as its name implies, prepares the xml document. This stored procedure needs to be called before a call to openxml.
Line 17: Weâre getting the data from the xml document and inserting it into the table. The @handle is the handle returned by sp_xml_preparedocument, theâROOT/Threadâ is the XPATH that tells OPENXML which rows to process, and the 2 describes the mapping between OPENXMLâs rowset and the XML Document. This last parameter is optional. The default mapping is attribute-centric mapping, which we would use if our XML structure was like the following:
- â¦
- <TGuid value=âThe guid goes hereâ />
- <TData value=âAn awful lot of dataâ />
- â¦
Line 19: Weâre basically telling how to format the data we get from OPENXML.
Line 21: The XML Document that SQL Server created is stored in memory. To avoid memory leaks, we close the handle.
So, What Kind of Savings Can We Expect?

Two things to notice:
- The savings become more and more significant as the number of records weâre inserting becomes larger.
- Even when weâre inserting only 50 records, the difference is noticeable (about .34 seconds).