I’ve currently got a C# application that responds to HTTP requests. The body of the HTTP request (XML) is passed to SQL Server, at which time the database engine performs the correct instruction. One of the instructions is used to load information about Invoices using the id of the customer(InvoiceLoad):
<InvoiceLoad ControlNumber="12345678901">
<Invoice>
<CustomerID>johndoe@gmail.com</CustomerID>
</Invoice>
</InvoiceLoad>
I need to perform a SELECT operation against the invoice table (which contains the associated email address).
I’ve tried using:
SELECT 'Date', 'Status', 'Location'
FROM Invoices
WHERE Email_Address = Invoice.A.value(.)
using an xml.nodes('InvoiceLoad/Invoice/CustomerId') Invoice(A)
command.
However, as this query may run THOUSANDS of times per minute, I want to make it as fast as possible. I’m hearing that one way to do this may be to use CROSS APPLY (which I have never used). Is that the solution? If not, how exactly would I go about making this query as fast as possible? Any and all suggestions are greatly appreciated!
I don’t see why you would need a call to
.nodes()at all – from what I understand, each XML fragment has just a single entry – right?So given this XML:
you can use this SQL to get the value of the
<CustomerID>node:and you can join this against your customer table or whatever you need to do.
If you have the XML stored in a table, and you always need to extract that value from
<CustomerID>, you could also think about creating a computed, persisted column on that table that would extract that e-mail address into a separate column, which you could then use for easy joining. This requires a little bit of work – a stored function taking theXMLas input – but it’s really quite a nice way to “surface” certain important snippets of data from your XML.Step 1: create your function
So given your XML, you get the one
<CustomerID>node and extract its “inner text” and return it as aVARCHAR(255).Step 2: add a computed, persisted column to your table
Now, your table that has the XML column has a new column –
CustomerID– which will automagically contain the contents of the<CustomerID>as aVARCHAR(255). The value is persisted, i.e. as long as the XML doesn’t change, it doesn’t have to be re-computed. You can use that column like any other on your table, and you can even index it to speed up any joins on it!