The XML data type, introduced in SQL Server 2005. XML data type can store either a complete XML or a fragment of XML document. Before xml data type the xml data was stored in varchar or text data type, that was proven to be poor in terms of querying and manipulating the XML data.
When to use XML data type:- If one wants to store the XML document in the database and retrieve and update the document as a whole - that is, if you never need to query or modify the individual XML components - you should consider using one of the large object data types like VARCHAR(MAX), NVARCHAR(MAX) or VARINARY(MAX).
- If you want to preserve the original form such as legal documents or want to retain an exact textual copy, use large object storage.
- The rest of the time, one should consider using XML data type which ensures that the data is well formed according to ISO standards, and supports fine-grained queries and modifications to specific elements and attributes within the XML. One can also index an XML column and associate its data with an XML schema collection in order to preserve its content and structure.
- This cannot be used as a key in an index
- Cannot exceed 2 GB size
- XML data type cannot be compared, sorted, or used in GROUP BY
- It does not support casting or converting to either text or ntext
- It cannot be used as a parameter to any scalar, or built-in functions other than ISNULL, COALESCE and DATALENGTH
Below is the sample XML used to walk through the manipulations:
<Employees>SELECTing Employee Name, Department and Address for the given Employee ID
<Employee><ID>1</ID><Name>John Test</Name><Department>IT</Department><Address><Street1>4404, Main Road</Street1><Street2/><City>Reston</City><State>VA</State><Zip>20171</Zip></Address></Employee><Employee><ID>2</ID><Name>King George</Name><Department>Admin</Department><Address><Street1>3004, St. Patric Road</Street1><Street2>Apt D</Street2><City>Vienna</City><State>VA</State><Zip>20171</Zip></Address></Employee></Employees>
SELECTUPDATing Street2 of Address for the given Employee IDt.c.value('Name[1]', 'varchar(max)') as 'Employee Name',t.c.value('Department[1]', 'varchar(max)') as 'Department',t1.c1.value('Street1[1]', 'varchar(max)') + ', ' +t1.c1.value('Street2[1]', 'varchar(max)') +-- Conditionalyy append comma based on Street2 value, Append when Street2 available else don'tcase when ((t1.c1.value('Street2[1]', 'varchar(max)') != '')) then (', ') else ('') end +t1.c1.value('City[1]', 'varchar(max)') + t1.c1.value('State[1]', 'varchar(max)') + ' - ' +t1.c1.value('Zip[1]', 'varchar(max)') as 'Address'FROM@XML.nodes('//Employees/Employee') as t(c)CROSS APPLY t.c.nodes('Address') as t1(c1)WHEREt.c.value('ID[1]', 'int') = 1
SET @employeeID = 2 -- Provide employee IDDELETing Street2 of Address for the given Employee ID
-- Check for provided employee ID and if Street2 value is NULL
IF @Xml.exist('/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street2/text()') = @employeeID
BEGIN -- will execute for employeeID = 2PRINT 'First Part'SET
@Xml.modify('replace value of (/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street2/text())[1] with "Apt F"')ENDELSE -- IF Street2 tag value is present execute belowBEGIN -- will execute for employeeID = 1PRINT 'Second Part'SET @Xml.modify('delete (/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street2)')SET @Xml.modify('insert (<Street2>Apt A</Street2>) after (/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street1)[1]')ENDSELECT @Xml
SET @employeeID = 1 -- Provide employee IDINSERTing Street3 after Street2 of Address for the given Employee ID
BEGINSET @Xml.modify('delete (/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street2)')ENDSELECT @Xml
SET @employeeID = 1 -- Provide employee ID
BEGINSET @Xml.modify('insert (<Street3>Near</Street3>) after (/Employees/Employee/ID[text()=sql:variable("@employeeID")]/../Address/Street2)[1]')ENDSELECT @Xml