Tuesday, November 21, 2006

Passing Multiple-value With XML In SQL Server 2005

The XML functions has been improved a lot in SQL Server 2005. Suppose there's a simple Contacts table:
Contacts(Name varchar(100), Phone varchar(100), Email varchar(100))
The application is sending following XML data to SQL Server for Contacts update (simply string type for ADO.NET parameter):
<Contacts>
<Contact>
<Name>Name ABC</Name>
<Phone>111-222-3333</Phone>
<Email>abc@abc.com</Email>
</Contact>
<Contact>
<Name>Name BCD</Name>
<Phone>222-333-4444</Phone>
<Email>bcd@bcd.com</Email>
</Contact>
</Contacts>
The stored procedure takes the XML as parameter and parse it internally:
CREATE PROCEDURE [dbo].[Update_ContactsByXml]
(
@Contacts xml
)
AS
BEGIN
SET NOCOUNT ON
-- Create a temp table to hold the values
declare @tmpItems table
(
Name varchar(100),
Phone varchar(100),
Email varchar(100)
)
-- Insert all Ids to temp table
INSERT INTO @tmpItems
SELECT TMPXML.Nodes.value('./Name[1]', 'varchar(100)') as Name,
TMPXML.Nodes.value('./Phone[1]', 'varchar(100)') as Phone,
TMPXML.Nodes.value('./Email[1]', 'varchar(100)') as Email
FROM @Contacts.nodes('//Contacts/Contact') TMPXML (Nodes)

-- Update existing contacts
UPDATE C SET Phone = T.Phone, Email = T.Email
FROM @tmpItems T INNER JOIN Contacts C ON T.Name = C.Name

-- Insert new contacts
INSERT INTO Contacts
SELECT * FROM @tmpItems WHERE Name NOT IN (SELECT Name FROM Contacts)
END
One advantage of using XML to pass multi-value is that it's not vulnerable to SQL injection attack.