Mufaka
Tue Mar 04 23:31:06 CST 2008
mj2736@yahoo.com wrote:
> In our .Net 2.0 web service we need to insert/update data records into
> SQL Server 2005 that have been uploaded to us in XML documents. There
> could be anywhere from one to literally thousands of records in each
> uploaded transaction, and there are several dozen destination tables.
>
> Since performance is critical for this particular app, we were
> thinking of combining the stored procedure calls into configurable-
> sized batches using CommandType.Text and multiple concatenated EXEC
> statements, so we minimize database roundtrips as opposed to calling
> each SP individually in its own SqlCommand.
>
> Is this a good approach? One concern is that SQL Server would have to
> compile each and every batch since they will all be different, and the
> overhead involved in this could become significant. Is this really
> something to worry about, or not? Wouldn't a few batch compiles per
> transaction still be better than potentially thousands of roundtrips?
> Are there other problems with this approach?
>
> Of course we are planning to stress test to see how it actually
> responds, but I just wanted to get some opinions first in case someone
> has done this before and can give advice/recommendations/suggestions
> before we get too far into it.
>
> Thanks!
> MJ
For SQL 2005, I would use SQL's built in XML processing. You can pass
the xml text in as a parameter to a stored procedure.
Here's a snippet from what I have done with something similar:
/*
declare @XmlDoc nvarchar(4000)
set @XmlDoc =
'<patient>
<answer>
<PatientID>13303</PatientID>
<QuestionID>200</QuestionID>
<AppointmentID>105084</AppointmentID>
<AnswerValue>217,218</AnswerValue>
<SaveTypeID>1</SaveTypeID>
</answer>
</patient>'
exec up_PatientAnswer_Save_FromXml @XmlDoc = @XmlDoc
*/
ALTER procedure [dbo].[up_PatientAnswer_Save_FromXml]
(
@XmlDoc ntext
)
as
set nocount on
declare @Answers table
(
AnswerID Int identity,
PatientID Int,
QuestionID Int,
AppoIntmentID Int,
SaveTypeID Int,
AnswerValue nvarchar(3900) null,
AnswerValueDate datetime null,
AnswerValueInt Int null
)
declare @Pointer Int
-- get a pointer to the parsed doc
exec sp_xml_preparedocument @Pointer output, @XmlDoc
-- insert Into the table var so we can dispose of the xml doc
-- and work with the data easier (better)
insert Into @Answers
(PatientID, QuestionID, AppointmentID, SaveTypeID, AnswerValue,
AnswerValueDate, AnswerValueInt)
select
PatientID, QuestionID, AppointmentID, SaveTypeID, AnswerValue,
AnswerValueDate, AnswerValueInt
from
openxml(@Pointer, '/patient/answer', 2)
with
(
PatientID int,
QuestionID int,
AppointmentID int,
SaveTypeID int,
AnswerValue nvarchar(3900),
AnswerValueDate datetime,
AnswerValueInt int
)
-- release the xml doc
exec sp_xml_removedocument @Pointer
-- processing from here is done with the data in the table variable
More info can be found here:
http://www.perfectxml.com/articles/xml/openxml.asp
If the XML that you receive is usable as is, you can just pass that
along. Or you can create new XML that is in a format that you expect.
You may also be able to us SqlBulkCopy to insert the data into a loading
table and have a stored procedure that works off of that table.
In SQL 2008, you will be able to pass a DataTable as a parameter to a
stored proc.